package orderhandler

import (
	"context"
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/gogap/logs"
	"github.com/shopspring/decimal"
	"log"
	"math/rand"
	"strconv"
	"time"
	"yundian/internel/app/dao"
	"yundian/internel/app/dao/memberdao"
	"yundian/internel/app/helper"
	"yundian/internel/app/helper/request"
	"yundian/internel/app/helper/resphelper"
	"yundian/internel/app/helper/resphelper/memberresp"
	"yundian/internel/app/logic"
	"yundian/internel/app/models/couponinfo"
	"yundian/internel/app/models/devices"
	"yundian/internel/app/models/dividendslog"
	"yundian/internel/app/models/membermodel"
	"yundian/internel/app/models/orderoperatelog"
	"yundian/internel/app/models/orders"
	"yundian/internel/app/models/ordersmonthly"
	"yundian/internel/app/models/placeincome"
	"yundian/internel/app/models/prices"
	"yundian/internel/app/models/users"
	"yundian/internel/pkg/authorized"
	"yundian/internel/pkg/dingo"
	"yundian/internel/pkg/dingo/global"
	. "yundian/internel/pkg/dingo/result"
	"yundian/internel/pkg/onlinesig"
	"yundian/internel/pkg/utils"
	_ "yundian/internel/pkg/utils"
	"yundian/internel/pkg/wechatpay"
)

const (
	GPP_APPID  string = "10068"
	GPP_SECRET string = "z0m903526004ce4b0est1a3940f5f92"
)

// HandleSendPlacePushData 发送推送数据-按月份
func HandleSendPlacePushData(ctx *gin.Context) {
	param := &request.SendPlacePushDataReq{}
	dingo.ErrorIf(ctx.ShouldBindJSON(&param)).Unwrap()
	param.IsAdmin, _ = helper.GetIsAdminFromCtx(ctx)
	param.ParentId, _ = helper.GetParentIdFromCtx(ctx)
	param.ProjectLabel = "hotel_jj"

	if !helper.IsAdminAndStaff(param.IsAdmin, param.ParentId) {
		Response(ctx)("帐号错误", CodeInvalidParam, nil)(OK)
		return
	}

	if err := logic.NewTaskLogic().GPPConsignmentCreation(param); err != nil {
		Response(ctx)(err.Error(), CodeError, false)(OK)
		return
	}

	Response(ctx)("", CodeSuccess, true)(OK)
}

// HandleGetPlacePushDataList 查询推送数据
func HandleGetPlacePushDataList(ctx *gin.Context) {
	param := &request.GetPlacePushDataListReq{}
	dingo.ErrorIf(ctx.ShouldBindJSON(&param)).Unwrap()
	param.IsAdmin, _ = helper.GetIsAdminFromCtx(ctx)
	param.ParentId, _ = helper.GetParentIdFromCtx(ctx)
	param.ProjectLabel = "hotel_jj"

	if !helper.IsAdminAndStaff(param.IsAdmin, param.ParentId) {
		Response(ctx)("帐号错误", CodeInvalidParam, nil)(OK)
		return
	}

	data := dao.NewStatisticalDao().GetPlacePushDataList(param)
	Response(ctx)("", CodeSuccess, ResponseList{
		PageNo:     param.PageNo,
		PageSize:   param.PageSize,
		TotalCount: data.Val().(int64),
		TotalPage:  (data.Val().(int64) + int64(param.PageSize) - 1) / int64(param.PageSize),
		Data:       data.Unwrap(),
	})(OK)
}

// HandleCreateGppPlacePushDataInMonth 生成推送数据-按月份
func HandleCreateGppPlacePushDataInMonth(ctx *gin.Context) {
	param := &request.CreateGppPlacePushDataReq{}
	dingo.ErrorIf(ctx.ShouldBindJSON(&param)).Unwrap()
	param.IsAdmin, _ = helper.GetIsAdminFromCtx(ctx)
	param.ParentId, _ = helper.GetParentIdFromCtx(ctx)
	param.ProjectLabel = "hotel_jj"

	if !helper.IsAdminAndStaff(param.IsAdmin, param.ParentId) {
		Response(ctx)("帐号错误", CodeInvalidParam, nil)(OK)
		return
	}

	data := dao.NewStatisticalDao().CreateGppPlacePushDataInMonth(param)
	Response(ctx)("", CodeSuccess, data.Err == nil)(OK)
}

// GetGppOrderDayDataList 周期付款订单-天统计
func GetGppOrderDayDataList(ctx *gin.Context) {
	param := make(request.DrawDeviceDiscountsReq)
	dingo.ErrorIf(ctx.ShouldBindJSON(&param)).Unwrap()
	param["secret"] = GPP_SECRET
	const gppAppid = GPP_APPID

	timeNum, _ := strconv.Atoi(param["time"])
	fmt.Println(timeNum, time.Now().Unix())
	if (int64(timeNum)+10) < time.Now().Unix() || param["appid"] != gppAppid {
		Response(ctx)("", CodeInvalidParam, nil)(OK)
		return
	}

	paramStr := utils.EncodeAliPaySignParams(param)
	if sing := onlinesig.MD5(paramStr); sing != param["sing"] {
		Response(ctx)("验签失败", CodeInvalidParam, nil)(OK)
		return
	}

	tParam := &placeincome.GetGppPlaceIncomeListReq{Month: param["month"], HotelId: param["hotelId"], ProjectLabel: "hotel_jj"}
	data := dao.NewStatisticalDao().GetGppOrderDayDataListByHotelId(tParam)
	if data.Err != nil {
		Response(ctx)("", CodeError, nil)(OK)
		return
	}

	Response(ctx)("", CodeSuccess, data.Unwrap())(OK)
}

// GetGppOrderMonthDataList 周期付款订单-月统计
func GetGppOrderMonthDataList(ctx *gin.Context) {
	param := make(request.DrawDeviceDiscountsReq)
	dingo.ErrorIf(ctx.ShouldBindJSON(&param)).Unwrap()
	param["secret"] = GPP_SECRET
	const gppAppid = GPP_APPID

	timeNum, _ := strconv.Atoi(param["time"])
	fmt.Println(timeNum, time.Now().Unix())
	//if (int64(timeNum)+10) < time.Now().Unix() || param["appid"] != gppAppid {
	//	Response(ctx)("", CodeInvalidParam, nil)(OK)
	//	return
	//}

	paramStr := utils.EncodeAliPaySignParams(param)
	if sing := onlinesig.MD5(paramStr); sing != param["sing"] {
		Response(ctx)("验签失败", CodeInvalidParam, nil)(OK)
		return
	}

	tParam := &placeincome.GetGppPlaceIncomeListReq{Year: param["year"], HotelId: param["hotelId"], ProjectLabel: "hotel_jj"}
	data := dao.NewStatisticalDao().GetGppOrderDayMonthListByHotelId(tParam)
	if data.Err != nil {
		Response(ctx)("", CodeError, nil)(OK)
		return
	}

	Response(ctx)("", CodeSuccess, data.Unwrap())(OK)
}

// GetAutoPayOrderList 周期付款订单
func GetAutoPayOrderList(ctx *gin.Context) {
	isAdmin, err := helper.GetIsAdminFromCtx(ctx)
	dingo.ErrorIf(err).Unwrap()

	param := &request.AutoPayOrderListReq{}
	param.IsAdmin = isAdmin
	dingo.ErrorIf(ctx.ShouldBindJSON(param)).Unwrap()

	if isAdmin != helper.TypeNumIsAdminAdministrator &&
		isAdmin != helper.TypeNumIsAdminOperator && isAdmin != helper.TypeNumIsAdminStaff {
		Response(ctx)("", CodeInvalidParam, nil)(Unauthorized)
		return
	}

	data := dao.NewOrderAutoRenewDao().GetAutoRenewMonthlyOrderList(param)
	lists := data.Unwrap().([]*request.GetAutoRenewMonthlyAwaitListReq)

	// 分页信息
	Response(ctx)("", CodeSuccess, ResponseList{
		PageNo:     param.PageNo,
		PageSize:   param.PageSize,
		TotalCount: data.Val().(int64),
		TotalPage:  (data.Val().(int64) + int64(param.PageSize) - 1) / int64(param.PageSize),
		Data:       lists,
	})(OK)

}

// GetOrderList 获取定单列表API
func GetOrderList(ctx *gin.Context) {
	loginUserId, err := helper.GetUserIdFromCtx(ctx) // 获取当前登录用户ID
	isAdmin, err := helper.GetIsAdminFromCtx(ctx)    // 从上下文中获取用户是否为管理员
	parentId, err := helper.GetParentIdFromCtx(ctx)  // 从上下文中获取当前用户的上级ID
	isPlace, err := helper.GetIsPlaceFromCtx(ctx)
	IsDraw, err := helper.GetIsDrawFromCtx(ctx)
	if err != nil {
		Response(ctx)(err.Error(), CodeNeedLogin, nil)(Unauthorized)
		return
	}

	// 请求参数处理
	param := &request.OrderListReq{}
	param.LoginUserId = loginUserId // 当前登录用户ID
	param.IsAdmin = isAdmin         //角色类型 1:管理员 2:运营商 3:代理、商户 4:员工  5:合伙人
	param.IsPlace = isPlace
	param.ParentId = parentId // 当前登录账号的，上级ID
	param.IsDraw = IsDraw
	dingo.ErrorIf(ctx.ShouldBindQuery(param)).Unwrap()

	if isAdmin == helper.TypeNumIsAdminAdministrator || (isAdmin == helper.TypeNumIsAdminStaff && parentId == 2) {
		param.LoginUserId = 2
	}

	// 查询结果
	data := dao.NewOrderDao().GetOrderList(param, 0)
	lists := data.Unwrap().([]*orders.OrderList)

	// 分页信息
	Response(ctx)("", CodeSuccess, ResponseList{
		PageNo:     param.PageNo,
		PageSize:   param.PageSize,
		TotalCount: data.Val().(int64),
		TotalPage:  (data.Val().(int64) + int64(param.PageSize) - 1) / int64(param.PageSize),
		Data:       lists,
	})(OK)

}

// GetOrderListKf 获取定单列表API(客服)  客服专属使用
func GetOrderListKf(ctx *gin.Context) {
	loginUserId, err := helper.GetUserIdFromCtx(ctx) // 获取当前登录用户ID
	isAdmin, err := helper.GetIsAdminFromCtx(ctx)    // 从上下文中获取用户是否为管理员
	parentId, err := helper.GetParentIdFromCtx(ctx)  // 从上下文中获取当前用户的上级ID
	isPlace, err := helper.GetIsPlaceFromCtx(ctx)
	IsDraw, err := helper.GetIsDrawFromCtx(ctx)
	dingo.ErrorIf(err).Unwrap()

	// 请求参数处理
	param := &request.OrderListReq{}
	param.LoginUserId = loginUserId // 当前登录用户ID
	param.IsAdmin = isAdmin         //角色类型 1:管理员 2:运营商 3:代理、商户 4:员工  5:合伙人
	param.IsPlace = isPlace
	param.ParentId = parentId // 当前登录账号的，上级ID
	param.IsDraw = IsDraw
	dingo.ErrorIf(ctx.ShouldBindQuery(param)).Unwrap()

	// 查询结果
	data := dao.NewOrderDao().GetOrderListKf(param)
	lists := data.Unwrap().([]*orders.OrderList)

	// 分页信息
	Response(ctx)("", CodeSuccess, ResponseList{
		PageNo:     param.PageNo,
		PageSize:   param.PageSize,
		TotalCount: data.Val().(int64),
		TotalPage:  (data.Val().(int64) + int64(param.PageSize) - 1) / int64(param.PageSize),
		Data:       lists,
	})(OK)
}

// GetALLOrderListToKf 获取定单列表API(客服)  客服专属使用
func GetALLOrderListToKf(ctx *gin.Context) {
	loginUserId, err := helper.GetUserIdFromCtx(ctx) // 获取当前登录用户ID
	isAdmin, err := helper.GetIsAdminFromCtx(ctx)    // 从上下文中获取用户是否为管理员
	parentId, err := helper.GetParentIdFromCtx(ctx)  // 从上下文中获取当前用户的上级ID
	isPlace, err := helper.GetIsPlaceFromCtx(ctx)
	IsDraw, err := helper.GetIsDrawFromCtx(ctx)
	dingo.ErrorIf(err).Unwrap()

	// 请求参数处理
	param := &request.OrderListReq{}
	param.LoginUserId = loginUserId // 当前登录用户ID
	param.IsAdmin = isAdmin         //角色类型 1:管理员 2:运营商 3:代理、商户 4:员工  5:合伙人
	param.IsPlace = isPlace
	param.ParentId = parentId // 当前登录账号的，上级ID
	param.IsDraw = IsDraw
	dingo.ErrorIf(ctx.ShouldBindQuery(param)).Unwrap()

	// 查询结果
	data := dao.NewOrderDao().GetALLOrderListToKf(param)
	lists := data.Unwrap().([]*orders.OrderList)

	// 分页信息
	Response(ctx)("", CodeSuccess, ResponseList{
		PageNo:     param.PageNo,
		PageSize:   param.PageSize,
		TotalCount: data.Val().(int64),
		TotalPage:  (data.Val().(int64) + int64(param.PageSize) - 1) / int64(param.PageSize),
		Data:       lists,
	})(OK)
}

// GetOrderListYw 获取定单列表API(运营)  关闭
//func GetOrderListYw(ctx *gin.Context) {
//	loginUserId, err := helper.GetUserIdFromCtx(ctx) // 获取当前登录用户ID
//	if err != nil {
//		Response(ctx)(err.Error(), CodeNeedLogin, nil)(Unauthorized)
//		return
//	}
//	isAdmin, err := helper.GetIsAdminFromCtx(ctx) // 从上下文中获取用户是否为管理员
//	if err != nil {
//		Response(ctx)(err.Error(), CodeNeedLogin, nil)(Unauthorized)
//		return
//	}
//	parentId, err := helper.GetParentIdFromCtx(ctx) // 从上下文中获取当前用户的上级ID
//	if err != nil {
//		Response(ctx)(err.Error(), CodeNeedLogin, nil)(Unauthorized)
//		return
//	}
//	isPlace, err := helper.GetIsPlaceFromCtx(ctx)
//	if err != nil {
//		Response(ctx)(err.Error(), CodeNeedLogin, nil)(Unauthorized)
//		return
//	}
//	IsDraw, _ := helper.GetIsDrawFromCtx(ctx)
//
//	// 请求参数处理
//	param := &request.OrderListReq{}
//	param.LoginUserId = loginUserId // 当前登录用户ID
//	param.IsAdmin = isAdmin         //角色类型 1:管理员 2:运营商 3:代理、商户 4:员工  5:合伙人
//	param.IsPlace = isPlace
//	param.ParentId = parentId // 当前登录账号的，上级ID
//	param.IsDraw = IsDraw
//	dingo.ErrorIf(ctx.ShouldBindQuery(param)).Unwrap()
//
//	// 查询结果
//	data := dao.NewOrderDao().GetOrderListYw(param)
//	lists := data.Unwrap().([]*orders.OrderModel)
//	for _, lst := range lists {
//		userInfo := dao.NewUserDao().GetUserByPlaceId(lst.PlaceId).Unwrap().(*users.UserModel)
//		lst.UserNo = userInfo.UserNo
//		//lst.MemberName = helper.GetPhoneStr(lst.MemberName)
//		//lst.MemberPhone = helper.GetPhoneStr(lst.MemberPhone)
//		//if lst.Phone == lst.UserName {
//		//	lst.UserName = helper.GetPhoneStr(lst.UserName)
//		//}
//	}
//	// 分页信息
//	Response(ctx)("", CodeSuccess, ResponseList{
//		PageNo:     param.PageNo,
//		PageSize:   param.PageSize,
//		TotalCount: data.Val().(int64),
//		TotalPage:  (data.Val().(int64) + int64(param.PageSize) - 1) / int64(param.PageSize),
//		Data:       lists,
//	})(OK)
//}

func GetOrderCount(ctx *gin.Context) {

	loginUserId, err := helper.GetUserIdFromCtx(ctx) // 获取当前登录用户ID
	if err != nil {
		Response(ctx)(err.Error(), CodeNeedLogin, nil)(Unauthorized)
		return
	}
	isAdmin, err := helper.GetIsAdminFromCtx(ctx) // 从上下文中获取用户是否为管理员
	if err != nil {
		Response(ctx)(err.Error(), CodeNeedLogin, nil)(Unauthorized)
		return
	}
	//parentId, err := helper.GetParentIdFromCtx(ctx) // 从上下文中获取当前用户的上级ID
	//if err != nil {
	//	Response(ctx)(err.Error(), CodeNeedLogin, nil)(Unauthorized)
	//	return
	//}
	//
	//isPlace, err := helper.GetIsPlaceFromCtx(ctx)
	//if err != nil {
	//	Response(ctx)(err.Error(), CodeNeedLogin, nil)(Unauthorized)
	//	return
	//}
	isDraw, err := helper.GetIsDrawFromCtx(ctx)
	Response(ctx)("", CodeSuccess, dao.NewOrderDao().CountOrder(isAdmin, loginUserId, isDraw).Unwrap())(OK)

	//Response(ctx)("", CodeSuccess, &struct {
	//	CountWeixin         int64 `json:"count_weixin"`
	//	CountZhifubao       int64 `json:"count_zhifubao"`
	//	CountStatusServing  int64 `json:"count_status_serving"`
	//	CountStatusReturned int64 `json:"count_status_returned"`
	//	CountStatusWaiting  int64 `json:"count_status_waiting"`
	//	CountStatusRevoked  int64 `json:"count_status_revoked"`
	//	CountSettMoney      int64 `json:"count_sett_money"`
	//}{
	//	CountWeixin:         dao.NewOrderDao().CountWeixin(isAdmin, loginUserId, isPlace, parentId).Unwrap().(int64),
	//	CountZhifubao:       dao.NewOrderDao().CountZhifubao(isAdmin, loginUserId, isPlace, parentId).Unwrap().(int64),
	//	CountStatusServing:  dao.NewOrderDao().CountStatusServing(isAdmin, loginUserId, isPlace, parentId).Unwrap().(int64),
	//	CountStatusReturned: dao.NewOrderDao().CountStatusReturned(isAdmin, loginUserId, isPlace, parentId).Unwrap().(int64),
	//	CountStatusRevoked:  dao.NewOrderDao().CountStatusRevoked(isAdmin, loginUserId, isPlace, parentId).Unwrap().(int64),
	//	CountStatusWaiting:  dao.NewOrderDao().CountStatusWaiting(isAdmin, loginUserId, isPlace, parentId).Unwrap().(int64),
	//	//CountSettMoney: dao.NewOrderDao().CountSettMoney().Unwrap().(int64),
	//})(OK)
}

// GetOrderDetail 获取定单详情API
func GetOrderDetail(ctx *gin.Context) {
	orderId := &struct {
		Id int `uri:"id" binding:"required,gt=0"`
	}{}
	dingo.ErrorIf(ctx.ShouldBindUri(orderId)).Unwrap()

	info := dao.NewOrderDao().GetOrderDetail(orderId.Id).Unwrap().(*resphelper.OrderInfoRes)                         // 订单信息
	logs.Info("订单详情=====>", info.TradeNo)
	info.DeviceInfo = dao.NewDeviceDao().FetchDeviceInfoWithType(info.DeviceSn).Unwrap().(*devices.DeviceType) // 获取设备信息
	if info.State == 5 {                                                                                       // 获取分成信息
		endTime := time.Unix(int64(info.EndAt), 0).Format("2006-01-02")
		info.DividendsList = dao.NewOrderDao().GetProfitInfo(info.TradeNo, endTime).Unwrap().([]dividendslog.ProfitInfo)
	}
	info.PriceInfo = dao.NewPricesDao().GetPriceDetail(info.ProductId).Unwrap().(*prices.PriceModel) // 获取价格信息

	// 计算使用费用、使用时长
	endTime := time.Now().Unix()
	var settResult *resphelper.SettlementResp
	var useTime, settMoney, returnMoney, reduceTime, reduceMoney int64

	if info.State == 2 {
		isCouponInfo, rowsAffected := dao.NewCouponDao().GetByOpenIdAndTradeNoCouponInfo(info.Openid, info.TradeNo) // 判断该用户是否有优惠券
		couponInfoModel := isCouponInfo.Unwrap().(*couponinfo.CouponInfo)
		if rowsAffected > 0 {
			switch couponInfoModel.Type {
			case 1: // 满减
			case 2: // 折扣
			case 3: // 现金
				reduceMoney = int64(couponInfoModel.Discounts)
			case 4: // 免费时长减免
				reduceTime = int64(couponInfoModel.Discounts)
			}
		}
		if info.FeeMode == 1 { // 计时模式
			settResult = logic.NewOrderLogic().GetOrderSettMoney(
				int64(info.BeginAt),
				endTime,
				info.PayMoney,
				info.PriceInfo,
				info.PayFrom,
				reduceTime,
			)
		} else { // feeMode == 2 套餐模式
			useTime = endTime - int64(info.PayAt)
			settMoney = info.PriceInfo.PayMoney
			returnMoney = 0
			if info.PayMoney > info.PriceInfo.PayMoney { // 支付的金额大于套餐用时最大金额
				returnMoney = info.PayMoney - info.PriceInfo.PayMoney
			}
			settResult = &resphelper.SettlementResp{
				UseTime:     useTime,
				SettMoney:   settMoney,
				ReturnMoney: returnMoney,
			}
		}
		if reduceMoney > 0 {
			if settResult.SettMoney < reduceMoney {
				reduceMoney = settResult.SettMoney
			}
			settResult.ReduceMoney = reduceMoney
			settResult.CouponType = int8(couponInfoModel.Type)
			settResult.SettMoney = settResult.SettMoney - reduceMoney
		}

		//最低支付金额低于优惠券这里就变负数导致不能正常结束,将结算金额改为0
		if settResult.SettMoney < 0 {
			settResult.SettMoney = 0
		}

		log.Println("打印结算结果 使用时长、结算金额、应退还金额", settResult) //
	} else {
		settResult = &resphelper.SettlementResp{
			UseTime:     int64(info.UpdateAt) - int64(info.BeginAt),
			SettMoney:   info.SettlementMoney,
			ReturnMoney: info.RefundMoney,
			ReduceMoney: 0,
			CouponType:  0,
		}
	}

	info.UseTime = settResult.UseTime
	info.UseMoney = settResult.SettMoney
	info.FetureTime = (int64(info.PriceInfo.MaxTime)*60 - info.UseTime) * 1000 // 毫秒

	//获取退款总额
	//total := dao.NewOrderDao().GetRefundsByTransactionIdTotal(info.OutTradeNo).Unwrap().(int64)
	total := dao.NewOrderDao().GetRefundsByTradeNoTotal(info.TradeNo).Unwrap().(int64)
	info.RefundMoney = total
	info.RefundMoneyStr = decimal.NewFromInt(total).Div(decimal.NewFromInt(100)).StringFixed(2)


	memberInfo := memberdao.NewMemberDao().GetMemberInfoByUuId(info.MemberId).Unwrap().(*membermodel.MembersModel)
	info.Balance = decimal.NewFromInt(memberInfo.Balance).Div(decimal.NewFromInt(100)).StringFixed(2)
	info.MemberPclBalanceList = memberdao.NewMemberDao().GetMemberPclBalanceLogByMemberId(memberInfo.ID, info.TradeNo).Unwrap().([]*memberresp.MemberPclBalanceRes)
	orderTotal := memberdao.NewMemberDao().SumMemberOrderByTradeNo(info.TradeNo).Unwrap().(int64)
	info.OrderTotal = decimal.NewFromInt(orderTotal).Div(decimal.NewFromInt(100)).StringFixed(2)
	if memberInfo.Balance > 0 && memberInfo.Balance >= orderTotal && orderTotal > 0 {
		info.IsCash = 1
	} else {
		info.IsCash = 2
	}

	Response(ctx)("", CodeSuccess, info)(OK)
}

// ExportOrderList 导出订单列表
//func ExportOrderList(ctx *gin.Context) {
//	// 请求参数处理
//	param := &request.OrderListReq{}
//	dingo.ErrorIf(ctx.ShouldBindQuery(param)).Unwrap()
//
//	// 查询结果
//	data := dao.NewOrderDao().GetOrderList(param)
//
//	Response(ctx)("", CodeSuccess, data.Unwrap())(OK)
//}

// 导出近3天的重复订单
func ExportRepeatOrderList(ctx *gin.Context) {
	// 请求参数处理
	param := &request.OrderListReq{}
	dingo.ErrorIf(ctx.ShouldBindQuery(param)).Unwrap()

	data := dao.NewOrderDao().ExportRepeatOrder(param)

	Response(ctx)("", CodeSuccess, data.Unwrap())(OK)
}

// 取消订单、退款
func HandelCancelAutoOrder(ctx *gin.Context) {
	userId, err := helper.GetUserIdFromCtx(ctx)
	userName, _ := helper.GetUserNameFromCtx(ctx)
	dingo.ErrorIf(err).Unwrap()

	// 获取参数
	param := &struct {
		TradeNo    string `json:"tradeNo" binding:"required"`
		CreateTime string `json:"createTime" form:"createTime"` // 防止重复订单
	}{}
	dingo.ErrorIf(ctx.ShouldBindJSON(param)).Unwrap()

	orderInfo, err := dao.NewOrderAutoRenewDao().GetAutoRenewOrderByTradeNo(param.TradeNo)
	if orderInfo.Id == 0 || err != nil {
		Response(ctx)("", CodeInvalidParam, false)(OK)
		return
	}

	c := logic.NewAliPayOrderLogicAppid(orderInfo.AppId, orderInfo.TradeNo)
	aliRsp, err := c.AliPayTradeRefund(int64(orderInfo.Amount), orderInfo.TradeNo, "订单退款")
	if err != nil || aliRsp.Response.Code != "10000" {
		Response(ctx)("退款失败", CodeError, false)(OK)
		return
	}

	update := &ordersmonthly.OrderMonthlyModel{
		OrderMonthlyDB: ordersmonthly.OrderMonthlyDB{
			TradeNo:     param.TradeNo,
			Status:      helper.TypeNumOrderMonthlyStatusRepeal,
			RenewStatus: helper.TypeNumOrderMonthlyRenewStatusClose,
		},
	}
	if data := dao.NewOrderAutoRenewDao().UpdateAutoRenewMonthlyPay(update); data.Err != nil {
		logs.Error("UpdateAutoRenewMonthlyPay", data.Err)
		return
	}
	fmt.Println("HandelCancelAutoOrder", userId, userName, param.TradeNo)
	Response(ctx)("订单撤销成功", CodeSuccess, true)(OK)
}

// 取消订单、退款
func HandelCancelOrder(ctx *gin.Context) {
	userId, err := helper.GetUserIdFromCtx(ctx) // 获取当前登录用户ID
	if err != nil {
		Response(ctx)(err.Error(), CodeNeedLogin, nil)(Unauthorized)
		return
	}

	userName, err := helper.GetUserNameFromCtx(ctx) // 获取当前登录用户名
	if err != nil {
		Response(ctx)(err.Error(), CodeNeedLogin, nil)(Unauthorized)
		return
	}

	//userId := 1
	//userName := "Test"
	//var err error
	// 获取参数
	param := &struct {
		TradeNo    string `json:"tradeNo" binding:"required"`
		CreateTime string `json:"createTime" form:"createTime"` // 防止重复订单
	}{}
	dingo.ErrorIf(ctx.ShouldBindJSON(param)).Unwrap()

	// 添加订单操作日志
	orderLog := orderoperatelog.OrderOperateLog{}
	orderLog.TradeNo = param.TradeNo
	orderLog.UserId = userId
	orderLog.UserName = userName
	orderLog.OperateType = 8
	orderLog.OperateIP = ctx.ClientIP()
	////修改统计
	//logic.NewOrderLogic().AgainStatistical(param.TradeNo)

	//查询订单
	orderInfo := dao.NewOrderDao().GetOrderInfoByTradeNo(param.TradeNo).Unwrap().(*orders.OrderModel)
	if orderInfo.OrderFrom == "zhifubao" {
		rMoney := orderInfo.SettlementMoney
		outRequestNo := orderInfo.OutTradeNo
		if orderInfo.State == 2 {
			rMoney = orderInfo.PayMoney
			outRequestNo = orderInfo.TradeNo
		}

		var settResult resphelper.SettlementResp
		settResult.SettMoney = orderInfo.SettlementMoney
		settResult.ReturnMoney = orderInfo.SettlementMoney

		logs.Info(rMoney, orderInfo.TradeNo, "订单退款")
		c := logic.NewAliPayOrderLogicAppid(orderInfo.Appid, orderInfo.TradeNo)
		aliRsp, err := c.AliPayTradeRefund(rMoney, outRequestNo, "订单退款")
		if err != nil || aliRsp.Response.Code != "10000" {
			Response(ctx)("退款失败", CodeError, false)(OK)
			return
		}

		// 验证退款成功后再执行
		dingo.Task(logic.NewOrderLogic().UpdateOrderInfo, func() {}, orderInfo.Id, &settResult, time.Now().Unix())
	} else {
		err = logic.NewOrderLogic().HandleWxCancelOrder(param.TradeNo, param.CreateTime)
		if err != nil {
			orderLog.ErrorType = int(CodeError)
			orderLog.ErrorMessage = "全额退款失败"

			dingo.Task(logic.NewLogsLogic().InsertOrderLogLogic, func() {}, orderLog) // 添加订单操作日志

			Response(ctx)(err.Error(), CodeError, false)(OK)
			return
		}
	}

	//全额退款直接删除分红
	dao.NewOrderDao().DeleteDividendsLog(param.TradeNo).Unwrap()
	dao.NewOrderDao().UpdateOrderStatus(param.TradeNo, 3).Unwrap()

	// 添加订单操作日志
	dingo.Task(logic.NewLogsLogic().InsertOrderLogLogic, func() {}, orderLog)

	Response(ctx)("订单撤销成功", CodeSuccess, true)(OK)
}

// 取消订单、退款
func HandelCancelOrderByMoney(ctx *gin.Context) {
	userId, err := helper.GetUserIdFromCtx(ctx) // 获取当前登录用户ID
	if err != nil {
		Response(ctx)(err.Error(), CodeNeedLogin, nil)(Unauthorized)
		return
	}

	userName, err := helper.GetUserNameFromCtx(ctx) // 获取当前登录用户名
	if err != nil {
		Response(ctx)(err.Error(), CodeNeedLogin, nil)(Unauthorized)
		return
	}

	// 获取参数
	param := &struct {
		TradeNo string `json:"tradeNo" binding:"required"`
		Money   string  `json:"money" form:"money"`
	}{}
	dingo.ErrorIf(ctx.ShouldBindJSON(param)).Unwrap()

	d,_ := decimal.NewFromString(param.Money)
	money := d.Mul(decimal.NewFromInt(100)).IntPart()

	// 添加订单操作日志
	orderLog := orderoperatelog.OrderOperateLog{}
	orderLog.TradeNo = param.TradeNo
	orderLog.UserId = userId
	orderLog.UserName = userName
	orderLog.OperateType = 7
	orderLog.OperateIP = ctx.ClientIP()

	//查询订单
	orderInfo := dao.NewOrderDao().GetOrderInfoByTradeNo(param.TradeNo).Unwrap().(*orders.OrderModel)

	if money > orderInfo.SettlementMoney {
		Response(ctx)("退款金额不能大于原始金额", CodeError, false)(OK)

		orderLog.ErrorType = int(CodeError)
		orderLog.ErrorMessage = "退款金额不能大于原始金额"

		dingo.Task(logic.NewLogsLogic().InsertOrderLogLogic, func() {}, orderLog) // 添加订单操作日志
		return
	}

	//refundsTotal := dao.NewOrderDao().GetRefundsByTransactionIdTotal(orderInfo.OutTradeNo).Unwrap().(int64)
	//if orderInfo.PayMoney < refundsTotal+param.Money {
	//	Response(ctx)("退款金额不能大于原始金额", CodeError, false)(OK)
	//	return
	//}

	if orderInfo.OrderFrom == "zhifubao" {
		//devInfo := dao.NewPlaceDao().GetPlaceInfoByDeviceSn(orderInfo.DeviceSn).Unwrap().(*devices.DeviceWithPlaceInfo) // 设备信息
		outRequestNo := orderInfo.OutTradeNo
		rMoney := orderInfo.SettlementMoney
		if orderInfo.State == 2 {
			rMoney = orderInfo.PayMoney
			outRequestNo = orderInfo.TradeNo
		}
		if money > 0 {
			rMoney = money
		}

		var settResult resphelper.SettlementResp
		settResult.SettMoney = orderInfo.SettlementMoney - rMoney
		settResult.ReturnMoney = rMoney

		c := logic.NewAliPayOrderLogicAppid(orderInfo.Appid, orderInfo.TradeNo)
		aliRsp, err := c.AliPayTradeRefund(rMoney, outRequestNo, "订单退款")
		if err != nil || aliRsp.Response.Code != "10000" {
			Response(ctx)("退款失败", CodeError, false)(OK)
			return
		}

		//// 验证退款成功后再执行
		//devInfo := dao.NewDeviceDao().FetchDeviceInfoWithType(orderInfo.DeviceSn).Unwrap().(*devices.DeviceType)
		//if dData := dao.NewOrderDao().DeleteDividendsLog(param.TradeNo); dData.Err != nil {
		//	fmt.Println("DeleteDividendsLog-err", dData.Err)
		//}
		//dingo.Task(logic.NewOrderLogic().CalOrderDividends, func() {}, orderInfo, devInfo, settResult.SettMoney, int64(orderInfo.EndAt))
		//dingo.Task(logic.NewOrderLogic().UpdateOrderInfo, func() {}, orderInfo.Id, &settResult, int64(orderInfo.EndAt))

		//refundsTotal := dao.NewOrderDao().GetRefundsByTransactionIdTotal(orderInfo.OutTradeNo).Unwrap().(int64)
		settlementMoney := decimal.NewFromInt(orderInfo.SettlementMoney).Sub(decimal.NewFromInt(rMoney)).IntPart()
		if settlementMoney <= 0 {
			dao.NewOrderDao().UpdateOrderState(orderInfo.Id, 3).Unwrap()     // 更新订单状态
			dao.NewOrderDao().DeleteDividendsLog(orderInfo.TradeNo).Unwrap() // 删除分红
		} else {
			dao.NewOrderDao().UpdateOrderSettlementMoney(orderInfo.Id, settlementMoney).Unwrap() // 修改订单结算金额
			devInfo := dao.NewOrderDao().GetDeviceInfo(orderInfo.DeviceSn).Unwrap().(*devices.DeviceType)
			dao.NewOrderDao().DeleteDividendsLog(orderInfo.TradeNo).Unwrap() // 删除分红
			dingo.Task(logic.NewOrderLogic().CalOrderDividends, func() {}, orderInfo, devInfo, settlementMoney, int64(orderInfo.EndAt))
		}
	} else {
		_, err = logic.NewOrderLogic().HandleWxCancelOrderByMoney(money, orderInfo)
		if err != nil {
			Response(ctx)(err.Error(), CodeError, false)(OK)
			orderLog.ErrorType = int(CodeError)
			orderLog.ErrorMessage = "退款失败"

			dingo.Task(logic.NewLogsLogic().InsertOrderLogLogic, func() {}, orderLog) // 添加订单操作日志
			return
		}
	}

	//dividends := orderInfo.PayMoney - (refundsTotal + param.Money)
	//if dividends <= 0 {
	//	log.Println("退款金额大于结算金额", orderInfo.TradeNo)
	//	orderInfo.State = 3
	//	dao.NewOrderDao().UpdateOrder(orderInfo).Unwrap()
	//
	//	logic.NewOrderLogic().AgainStatistical(orderInfo.TradeNo)
	//	//存在分红金额，删除之前分红数据
	//	dao.NewOrderDao().DeleteDividendsLog(orderInfo.TradeNo).Unwrap()
	//}
	//
	//if dividends > 0 {
	//	log.Println("部分退款金额回调：", orderInfo.TradeNo)
	//	//存在分红金额，删除之前分红数据
	//	dao.NewOrderDao().DeleteDividendsLog(orderInfo.TradeNo).Unwrap()
	//
	//	//查询订单对应的设备信息
	//	deviceInfo := dao.NewOrderDao().GetDeviceInfo(orderInfo.DeviceSn).Unwrap().(*devices.DeviceType)
	//	orderModel := &orders.OrderModel{}
	//	orderModel.OutTradeNo = orderInfo.OutTradeNo
	//	orderModel.SettlementMoney = dividends
	//	orderModel.SettlementMoneyStr = decimal.NewFromInt(dividends).Div(decimal.NewFromInt(100)).StringFixed(2)
	//	dao.NewOrderDao().UpdateOrderByOutTradeNo(orderModel).Unwrap()
	//	//orderInfo.SettlementMoney = dividends
	//	//dingo.Task(NewOrderLogic().CalOrderDividends, func() {}, orderInfo, deviceInfo, dividends, int64(orderInfo.EndAt)) // 计算分红 - 异步任务
	//	logic.NewOrderLogic().CalOrderDividends(orderInfo, deviceInfo, dividends, int64(orderInfo.EndAt)) //同步分红，
	//	//修改统计，只修改金额不计算订单
	//	logic.NewOrderLogic().ByMoneyAgainStatistical(orderInfo.TradeNo)
	//}

	//if param.Money < orderInfo.SettlementMoney {
	//	//修改统计，只修改金额不计算订单
	//	logic.NewOrderLogic().ByMoneyAgainStatistical(param.TradeNo)
	//}
	//if param.Money == orderInfo.SettlementMoney {
	//	logic.NewOrderLogic().AgainStatistical(param.TradeNo)
	//}

	////修改统计
	//logic.NewOrderLogic().AgainStatistical(param.TradeNo)

	//dao.NewOrderDao().UpdateOrderStatus(param.TradeNo, 3).Unwrap()

	dingo.Task(logic.NewLogsLogic().InsertOrderLogLogic, func() {}, orderLog) // 添加订单操作日志

	Response(ctx)("退款成功", CodeSuccess, true)(OK)
}

func HandelCancelOrderByMoneyByTradeNo(ctx *gin.Context) {
	userId, err := helper.GetUserIdFromCtx(ctx) // 获取当前登录用户ID
	if err != nil {
		Response(ctx)(err.Error(), CodeNeedLogin, nil)(Unauthorized)
		return
	}

	userName, err := helper.GetUserNameFromCtx(ctx) // 获取当前登录用户名
	if err != nil {
		Response(ctx)(err.Error(), CodeNeedLogin, nil)(Unauthorized)
		return
	}

	// 获取参数
	param := &struct {
		TradeNo string `json:"tradeNo" binding:"required"`
		Money   string  `json:"money" form:"money"`
	}{}
	dingo.ErrorIf(ctx.ShouldBindJSON(param)).Unwrap()

	d,_ := decimal.NewFromString(param.Money)
	money := d.Mul(decimal.NewFromInt(100)).IntPart()

	// 添加订单操作日志
	orderLog := orderoperatelog.OrderOperateLog{}
	orderLog.TradeNo = param.TradeNo
	orderLog.UserId = userId
	orderLog.UserName = userName
	orderLog.OperateType = 7
	orderLog.OperateIP = ctx.ClientIP()

	//查询订单
	orderInfo := dao.NewOrderDao().GetOrderInfoByTradeNo(param.TradeNo).Unwrap().(*orders.OrderModel)
	if orderInfo.OrderFrom == "zhifubao" {
		_, err := logic.NewOrderLogic().HandleZfbCancelOrderCash(money, orderInfo)
		if err != nil {
			orderLog.ErrorType = int(CodeError)
			orderLog.ErrorMessage = "退款失败" + err.Error()
			dingo.Task(logic.NewLogsLogic().InsertOrderLogLogic, func() {}, orderLog) // 添加订单操作日志
			Response(ctx)(err.Error(), CodeError, false)(OK)
			return
		}
		Response(ctx)("退款成功", CodeSuccess, true)(OK)
		return
	} else {
		_, err = logic.NewOrderLogic().HandleWxCancelOrderCash(money, orderInfo)
		if err != nil {
			orderLog.ErrorType = int(CodeError)
			orderLog.ErrorMessage = "退款失败" + err.Error()
			dingo.Task(logic.NewLogsLogic().InsertOrderLogLogic, func() {}, orderLog) // 添加订单操作日志
			Response(ctx)(err.Error(), CodeError, false)(OK)
			return
		}

		dingo.Task(logic.NewLogsLogic().InsertOrderLogLogic, func() {}, orderLog) // 添加订单操作日志

		Response(ctx)("退款成功", CodeSuccess, true)(OK)
	}

}

// 后台- 手动完结订单
func HandelCompleteOrder(ctx *gin.Context) {

	userId, err := helper.GetUserIdFromCtx(ctx) // 获取当前登录用户ID
	if err != nil {
		Response(ctx)(err.Error(), CodeNeedLogin, nil)(Unauthorized)
		return
	}

	userName, err := helper.GetUserNameFromCtx(ctx) // 获取当前登录用户名
	if err != nil {
		Response(ctx)(err.Error(), CodeNeedLogin, nil)(Unauthorized)
		return
	}

	param := &request.CloseOrderReq{}
	dingo.ErrorIf(ctx.ShouldBindJSON(param)).Unwrap()
	orderInfo := orders.New()
	global.Orm.Table("orders").
		Where("trade_no = ?", param.TradeNo).
		Where("create_at = ?", wechatpay.StrTimeToInt(param.CreateTime)).
		Find(&orderInfo)
	param.EndTime = time.Now().Unix()
	if param.Openid == "" {
		m := membermodel.New()
		global.Orm.Table("members").Where("uuid = ?", orderInfo.MemberId).Find(m)
		param.Openid = m.XcxOpenid
	}
	log.Println("打印测试数据-后台结算订单请求参数", param)
	param.ProductId = orderInfo.ProductId
	respData := logic.NewOrderLogic().HandleWxEndOrder(param)
	log.Println("打印完结订单返回结果 ------ ", respData)

	// 添加订单操作日志
	orderLog := orderoperatelog.OrderOperateLog{}
	orderLog.TradeNo = param.TradeNo
	orderLog.UserId = userId
	orderLog.UserName = userName
	orderLog.OperateType = 2
	orderLog.OperateIP = ctx.ClientIP()
	if err != nil {
		orderLog.ErrorType = int(CodeError)
		orderLog.ErrorMessage = err.Error()
	}

	dingo.Task(logic.NewLogsLogic().InsertOrderLogLogic, func() {}, orderLog)

	if err != nil {
		Response(ctx)(err.Error(), CodeError, false)(OK)
		return
	}
	Response(ctx)("订单完结成功", CodeSuccess, true)(OK)
}

// 恢复抽单订单、恢复奖励订单
func HandelBakOrder(ctx *gin.Context) {
	userId, err := helper.GetUserIdFromCtx(ctx) // 获取当前登录用户ID
	if err != nil {
		Response(ctx)(err.Error(), CodeNeedLogin, nil)(Unauthorized)
		return
	}

	userName, err := helper.GetUserNameFromCtx(ctx) // 获取当前登录用户名
	if err != nil {
		Response(ctx)(err.Error(), CodeNeedLogin, nil)(Unauthorized)
		return
	}

	param := &request.CloseOrderReq{}
	dingo.ErrorIf(ctx.ShouldBindJSON(param)).Unwrap()
	orderInfo := orders.New()
	global.Orm.Table("orders").
		Where("trade_no = ?", param.TradeNo).
		Where("create_at = ?", wechatpay.StrTimeToInt(param.CreateTime)).
		Find(&orderInfo)
	devInfo := dao.NewDeviceDao().FetchDeviceInfoWithType(param.DeviceSn).Unwrap().(*devices.DeviceType)
	if orderInfo.State == 5 {
		dao.NewOrderDao().UpdateOrderIsDraw(orderInfo)
		dao.NewOrderDao().DeleteDividendsLog(orderInfo.TradeNo).Unwrap()
		dingo.Task(logic.NewOrderLogic().CalOrderDividends, func() {}, orderInfo, devInfo, orderInfo.SettlementMoney, int64(orderInfo.EndAt)) // 计算分红 - 异步任务

		orderLog := orderoperatelog.OrderOperateLog{}
		orderLog.TradeNo = param.TradeNo
		orderLog.UserId = userId
		orderLog.UserName = userName
		orderLog.OperateType = 5
		orderLog.OperateIP = ctx.ClientIP()

		dingo.Task(logic.NewLogsLogic().InsertOrderLogLogic, func() {}, orderLog) // 添加订单操作日志
	}
	dao.NewOrderDao().UpdateOrderIsDraw(orderInfo)
	Response(ctx)("恢复成功", CodeSuccess, "SUCCESS")(OK)
}

// 订单同步
func HandelSyncOrder(ctx *gin.Context) {
	userId, err := helper.GetUserIdFromCtx(ctx) // 获取当前登录用户ID
	if err != nil {
		Response(ctx)(err.Error(), CodeNeedLogin, nil)(Unauthorized)
		return
	}

	userName, err := helper.GetUserNameFromCtx(ctx) // 获取当前登录用户名
	if err != nil {
		Response(ctx)(err.Error(), CodeNeedLogin, nil)(Unauthorized)
		return
	}

	param := &struct {
		TradeNo string `json:"tradeNo" form:"tradeNo"`
	}{}
	dingo.ErrorIf(ctx.ShouldBindJSON(param)).Unwrap()

	orderInfo := orders.New()
	global.Orm.Table("orders").
		Where("trade_no = ?", param.TradeNo).
		Find(&orderInfo)
	wc := logic.NewSettingLogic().GetPaySetting()
	// 查询微信订单信息
	resultData, err := wechatpay.ApiQueryPayScoreOrder(param.TradeNo, wc) // 查询微信订单
	if err != nil {
		log.Println("微信订单查询失败")
	}
	log.Println("打印测试数据，查询微信订单结果", resultData)

	// 添加订单操作日志
	orderLog := orderoperatelog.OrderOperateLog{}
	orderLog.TradeNo = param.TradeNo
	orderLog.UserId = userId
	orderLog.UserName = userName
	orderLog.OperateType = 5
	orderLog.OperateIP = ctx.ClientIP()

	// 将查询的订单信息更新入库
	if resultData != nil {
		var b bool
		var stateDoning string
		if resultData.Get("state") == "DONE" {
			stateDoning = "COMPLETE"
		} else {
			stateDoning = resultData.Get("state_description")
		}
		var status int8
		var stateDesc string
		switch resultData.Get("state") {
		case "CREATED":
			status = 1 // CREATED 商户已创建服务订单
			stateDesc = "商户已创建服务订单"
		case "DOING":
			status = 2 // DOING 服务订单进行中
			stateDesc = "服务订单进行中"
		case "DONE":
			status = 5 // DONE 服务订单完成
			stateDesc = "服务订单完成"
		case "REVOKED":
			status = 3 // REVOKED 商户取消服务订单
			stateDesc = "商户取消服务订单"
		case "EXPIRED":
			status = 4 // EXPIRED 服务订单已失效
			stateDesc = "服务订单已失效"
		}

		// 结算金额大于0时才会返回 结算通知更新订单信息
		if resultData.Get("collection") != "" {
			apiData := wechatpay.NewPayData()
			_ = apiData.FromJsonStr(resultData.Get("collection"))
			state := apiData.Get("state")                                           // 状态 USER_PAYING：待支付 USER_PAID：已支付
			totalAmount, _ := strconv.ParseInt(apiData.Get("total_amount"), 10, 64) // 总金额
			//paying_amount := apiData.Get("paying_amount") // 待支付金额
			paidAmount, _ := strconv.ParseInt(apiData.Get("paid_amount"), 10, 64) // 已支付金额
			log.Println(state, totalAmount, paidAmount)                           // USER_PAID 100 0 100

			//log.Println(apiData.Get("details"))
			//var details []detailData
			var details []map[string]interface{}
			_ = json.Unmarshal([]byte(apiData.Get("details")), &details)
			var transactionId string
			if len(details) > 0 {
				transactionId = details[0]["transaction_id"].(string)
			}
			log.Println("打印测试订单详情", details)

			var s int8
			if state == "USER_PAYING" { // 待支付 --- 待守约
				s = 7
				m := orders.New()
				m.State = s
				m.Money = totalAmount
				m.MoneyStr = decimal.NewFromInt(totalAmount).Div(decimal.NewFromInt(100)).StringFixed(2)

				m.PayMoney = paidAmount
				m.PayMoneyStr = decimal.NewFromInt(paidAmount).Div(decimal.NewFromInt(100)).StringFixed(2)

				//m.PayAt = dingo.Time(wechatpay.ConvIntTime(fmt.Sprintf("%v", details[0]["paid_time"])))
				//m.SettlementState = 3
				//amount, _ := strconv.ParseInt(fmt.Sprintf("%v", details[0]["amount"]), 10, 64)
				//m.SettlementMoney = amount
				//m.SettlementMoneyStr = decimal.NewFromInt(amount).Div(decimal.NewFromInt(100)).StringFixed(2)
				m.TradeStateDesc = stateDesc
				m.TradeStateDoing = stateDoning
				m.TradeState = resultData.Get("state")
				m.TradeNo = resultData.Get("out_order_no")
				m.Openid = resultData.Get("openid")

				m.EndAt = dingo.Time(time.Now().Unix())
				m.OutTradeNo = transactionId

				b = dao.NewOrderDao().UpdateOrderByTradeNo(m).Unwrap().(bool)
			} else {
				s = status
				m := orders.New()
				m.State = s
				m.Money = totalAmount
				m.MoneyStr = decimal.NewFromInt(totalAmount).Div(decimal.NewFromInt(100)).StringFixed(2)

				m.PayMoney = paidAmount
				m.PayMoneyStr = decimal.NewFromInt(paidAmount).Div(decimal.NewFromInt(100)).StringFixed(2)

				m.PayAt = dingo.Time(wechatpay.ConvIntTime(fmt.Sprintf("%v", details[0]["paid_time"])))
				m.SettlementState = 3
				amount, _ := strconv.ParseInt(fmt.Sprintf("%v", details[0]["amount"]), 10, 64)
				m.SettlementMoney = amount
				m.SettlementMoneyStr = decimal.NewFromInt(amount).Div(decimal.NewFromInt(100)).StringFixed(2)
				m.TradeStateDesc = stateDesc
				m.TradeStateDoing = stateDoning
				m.TradeState = resultData.Get("state")
				m.TradeNo = resultData.Get("out_order_no")
				m.Openid = resultData.Get("openid")

				m.EndAt = dingo.Time(time.Now().Unix())
				m.OutTradeNo = transactionId

				b = dao.NewOrderDao().UpdateOrderByTradeNo(m).Unwrap().(bool)
			}

		} else {
			memInfo := memberdao.NewMemberDao().GetMemberInfoByOpenid(resultData.Get("openid")).Unwrap().(*membermodel.MembersModel)
			m := orders.New()
			m.State = status
			m.TradeStateDesc = stateDesc
			m.TradeStateDoing = stateDoning
			m.TradeState = resultData.Get("state")
			m.TradeNo = resultData.Get("out_order_no")
			m.Openid = resultData.Get("openid")
			m.MemberId = memInfo.UUID
			m.MemberName = memInfo.NickName
			b = dao.NewOrderDao().UpdateOrderByTradeNo(m).Unwrap().(bool)
		}
		if b == true { // 同步成功
			Response(ctx)("同步成功", CodeSuccess, "SUCCESS")(OK)
		} else { // 同步失败
			Response(ctx)("同步失败", CodeSuccess, "SUCCESS")(OK)
		}

		if !b {
			orderLog.ErrorType = int(CodeError)
			orderLog.ErrorMessage = "同步失败"
		}

	} else { // 不需要同步
		Response(ctx)("同步成功", CodeSuccess, "SUCCESS")(OK)
	}
	dingo.Task(logic.NewLogsLogic().InsertOrderLogLogic, func() {}, orderLog) // 添加订单操作日志

}

// 订单搜索
func HanleSearchOrder(ctx *gin.Context) {
	param := &struct {
		TradeNo string `gorm:"column:trade_no" json:"tradeNo"` // 商户订单号
	}{}
	dingo.ErrorIf(ctx.ShouldBindJSON(param)).Unwrap()

	orderInfo := orders.New()
	global.Orm.Table("orders").
		Where("trade_no = ?", param.TradeNo).
		Find(&orderInfo)
	// 查询微信订单信息
	wc := logic.NewSettingLogic().GetPaySetting()
	resultData, err := wechatpay.ApiQueryPayScoreOrder(param.TradeNo, wc) // 查询微信订单
	if err != nil {
		Response(ctx)("微信订单查询失败", CodeError, nil)(Error)
		return
	}

	var b bool
	if orderInfo.Id > 0 { // 有订单更新
		// 更新微信订单状态
		// 1:等待下单 2:使用中 3:已撤销 4:交易失败 5:已完成 6:支付超时 7:待守约 10:已删除 11: 转入退款
		var status int8
		var stateDesc, stateDoning string
		switch resultData.Get("state") {
		case "CREATED":
			status = 1 // CREATED 商户已创建服务订单
			stateDesc = "商户已创建服务订单"
		case "DOING":
			status = 2 // DOING 服务订单进行中
			stateDesc = "服务订单进行中"
		case "DONE":
			status = 5 // DONE 服务订单完成
			stateDesc = "服务订单完成"
		case "REVOKED":
			status = 3 // REVOKED 商户取消服务订单
			stateDesc = "商户取消服务订单"
		case "EXPIRED":
			status = 4 // EXPIRED 服务订单已失效
			stateDesc = "服务订单已失效"
		}
		if resultData.Get("state") == "DONE" {
			stateDoning = "COMPLETE"
		} else {
			stateDoning = resultData.Get("state_description")
		}

		// 结算金额大于0时才会返回 结算通知更新订单信息
		if resultData.Get("collection") != "" {
			apiData := wechatpay.NewPayData()
			_ = apiData.FromJsonStr(resultData.Get("collection"))
			state := apiData.Get("state")                                           // 状态 USER_PAYING：待支付 USER_PAID：已支付
			totalAmount, _ := strconv.ParseInt(apiData.Get("total_amount"), 10, 64) // 总金额
			//paying_amount := apiData.Get("paying_amount") // 待支付金额
			paidAmount, _ := strconv.ParseInt(apiData.Get("paid_amount"), 10, 64) // 已支付金额
			log.Println(state, totalAmount, paidAmount)                           // USER_PAID 100 0 100

			//log.Println(apiData.Get("details"))
			//var details []detailData
			var details []map[string]interface{}
			_ = json.Unmarshal([]byte(apiData.Get("details")), &details)
			var transactionId string
			if len(details) > 0 {
				transactionId = details[0]["transaction_id"].(string)
			}
			log.Println("打印测试订单详情", details)

			var s int8
			if state == "USER_PAYING" { // 待支付 --- 待守约
				s = 7
				m := orders.New()
				m.State = s
				m.Money = totalAmount
				m.MoneyStr = decimal.NewFromInt(totalAmount).Div(decimal.NewFromInt(100)).StringFixed(2)

				m.PayMoney = paidAmount
				m.PayMoneyStr = decimal.NewFromInt(paidAmount).Div(decimal.NewFromInt(100)).StringFixed(2)

				//m.PayAt = dingo.Time(wechatpay.ConvIntTime(fmt.Sprintf("%v", details[0]["paid_time"])))
				//m.SettlementState = 3
				//amount, _ := strconv.ParseInt(fmt.Sprintf("%v", details[0]["amount"]), 10, 64)
				//m.SettlementMoney = amount
				//m.SettlementMoneyStr = decimal.NewFromInt(amount).Div(decimal.NewFromInt(100)).StringFixed(2)
				m.TradeStateDesc = stateDesc
				m.TradeStateDoing = stateDoning
				m.TradeState = resultData.Get("state")
				m.TradeNo = resultData.Get("out_order_no")
				m.Openid = resultData.Get("openid")

				m.EndAt = dingo.Time(time.Now().Unix())
				m.OutTradeNo = transactionId

				b = dao.NewOrderDao().UpdateOrderByTradeNo(m).Unwrap().(bool)
			} else {
				s = status
				m := orders.New()
				m.State = s
				m.Money = totalAmount
				m.MoneyStr = decimal.NewFromInt(totalAmount).Div(decimal.NewFromInt(100)).StringFixed(2)

				m.PayMoney = paidAmount
				m.PayMoneyStr = decimal.NewFromInt(paidAmount).Div(decimal.NewFromInt(100)).StringFixed(2)

				m.PayAt = dingo.Time(wechatpay.ConvIntTime(fmt.Sprintf("%v", details[0]["paid_time"])))
				m.SettlementState = 3
				amount, _ := strconv.ParseInt(fmt.Sprintf("%v", details[0]["amount"]), 10, 64)
				m.SettlementMoney = amount
				m.SettlementMoneyStr = decimal.NewFromInt(amount).Div(decimal.NewFromInt(100)).StringFixed(2)
				m.TradeStateDesc = stateDesc
				m.TradeStateDoing = stateDoning
				m.TradeState = resultData.Get("state")
				m.TradeNo = resultData.Get("out_order_no")
				m.Openid = resultData.Get("openid")

				m.EndAt = dingo.Time(time.Now().Unix())
				m.OutTradeNo = transactionId

				b = dao.NewOrderDao().UpdateOrderByTradeNo(m).Unwrap().(bool)
			}

		} else { // 订单金额为0时
			m := orders.New()
			m.State = status
			m.TradeStateDesc = stateDesc
			m.TradeStateDoing = stateDoning
			m.TradeState = resultData.Get("state")
			m.TradeNo = resultData.Get("out_order_no")
			m.Openid = resultData.Get("openid")
			m.EndAt = dingo.Time(time.Now().Unix())
			b = dao.NewOrderDao().UpdateOrderByTradeNo(m).Unwrap().(bool)
		}
	} else { // 新增
		memInfo := memberdao.NewMemberDao().GetMemberInfoByOpenid(resultData.Get("openid")).Unwrap().(*membermodel.MembersModel)
		devInfo := dao.NewDeviceDao().FetchDeviceInfoWithType(resultData.Get("attach")).Unwrap().(*devices.DeviceType)
		//ployInfo := dao.NewPloysDao().GetPlacePloyInfo(devInfo.PlaceId, devInfo.SharedMode).Unwrap().(*ploys.PloyModel) // 获取商户最新奖励规则配置

		var priceList []prices.PriceModel
		if devInfo.FeeMode == 1 { // 计时
			priceList = dao.NewPricesDao().GetPlacePriceByTypeId(devInfo.PlaceId, devInfo.DeviceTypeId, 1, 1, "create_at desc").Unwrap().([]prices.PriceModel)
		} else { // 套餐
			priceList = dao.NewPricesDao().GetPlacePriceByTypeId(devInfo.PlaceId, devInfo.DeviceTypeId, 1, 1, "pay_money asc").Unwrap().([]prices.PriceModel)
		}

		userInfo := dao.NewUserDao().GetUserInfoByPlaceId(devInfo.PlaceId).Unwrap().(*users.UserModel)
		uInfo := dao.GetParentUserInfoById(userInfo)

		isDraw := 0 // 不抽单

		timeRange := &struct {
			StartTime string `json:"start_time"`
			EndTime   string `json:"end_time"`
		}{}
		_ = json.Unmarshal([]byte(resultData.Get("time_range")), timeRange)
		stamp := wechatpay.ConvIntTime(timeRange.StartTime)
		//stamp, _ := time.ParseInLocation("20060102150405", timeRange.StartTime, time.Local)
		money, _ := strconv.ParseInt(resultData.Get("total_amount"), 10, 64)

		// 1:等待下单 2:使用中 3:已撤销 4:交易失败 5:已完成 6:支付超时 7:待守约 10:已删除 11: 转入退款
		var status int8
		var stateDesc string
		switch resultData.Get("state") {
		case "CREATED":
			status = 1 // CREATED 商户已创建服务订单
			stateDesc = "商户已创建服务订单"
		case "DOING":
			status = 2 // DOING 服务订单进行中
			stateDesc = "服务订单进行中"
		case "DONE":
			status = 5 // DONE 服务订单完成
			stateDesc = "服务订单完成"
		case "REVOKED":
			status = 3 // REVOKED 商户取消服务订单
			stateDesc = "商户取消服务订单"
		case "EXPIRED":
			status = 4 // EXPIRED 服务订单已失效
			stateDesc = "服务订单已失效"
		}

		// 不存在  新增
		m := orders.New().Mutate(
			orders.WithAppid(resultData.Get("appid")),
			orders.WithDeviceSn(resultData.Get("attach")),
			orders.WithMchid(resultData.Get("mchid")),
			orders.WithOpenid(resultData.Get("openid")),
			orders.WithOutTradeNo(resultData.Get("order_id")),  // 微信订单号
			orders.WithTradeNo(resultData.Get("out_order_no")), // 商户订单号
			//orders.WithPayAt(dingo.Time(stamp.Unix())),                        // 支付时间
			orders.WithPayAt(dingo.Time(stamp)), // 支付时间
			//orders.WithTradeType(resultData.Get("trade_type")),                    // 订单支付类型 - 微信支付分支付
			orders.WithTradeType("PreAuthPay"), // 订单支付类型 - 微信支付分支付
			orders.WithMoney(money),
			orders.WithMoneyStr(decimal.NewFromInt(money).Div(decimal.NewFromInt(100)).StringFixed(2)),
			orders.WithTradeState(resultData.Get("state")), // 微信交易 状态
			orders.WithTradeStateDesc(stateDesc),           // 微信交易状态描述
			orders.WithTradeStateDoing(resultData.Get("state_description")),
			orders.WithCreateAt(dingo.Time(time.Now().Unix())),
			orders.WithState(status),
			orders.WithOrderFrom("weixin"),
			orders.WithPayFrom(1), // 1免押 2押金
			orders.WithMemberId(memInfo.UUID),
			orders.WithMemberName(memInfo.NickName),
			orders.WithPlaceId(devInfo.PlaceId),
			orders.WithPlaceName(devInfo.PlaceName),
			orders.WithSharedMode(devInfo.SharedMode),
			orders.WithPayMoney(money),
			orders.WithPayMoneyStr(decimal.NewFromInt(money).Div(decimal.NewFromInt(100)).StringFixed(2)),
			orders.WithTitle(devInfo.DeviceName),
			orders.WithFeeMode(int8(devInfo.FeeMode)),
			orders.WithPayType(3),
			orders.WithProductId(priceList[0].ProductId),
			orders.WithIsDraw(int8(isDraw)), // 1抽单 0不抽单
			orders.WithIsTianHai(0),         // 0新系统  1天海
			orders.WithUserId(userInfo.ID),
			orders.WithUserName(userInfo.Name),
			orders.WithParentId(userInfo.ParentID),
			orders.WithAgentUserId(uInfo.ID),
			orders.WithSettlementWay(1),           // 未结算
			orders.WithProdType(devInfo.ProdType), // 设备类型  1  2  3
		)
		b = dao.NewOrderDao().InsertOrder(m).Unwrap().(bool)
	}

	Response(ctx)("", CodeSuccess, b)(OK)

}

//押金支付订单同步
func HandleWeChatPaySearchOrder(c *gin.Context) {

	userId, err := helper.GetUserIdFromCtx(c) // 获取当前登录用户ID
	if err != nil {
		Response(c)(err.Error(), CodeNeedLogin, nil)(Unauthorized)
		return
	}

	userName, err := helper.GetUserNameFromCtx(c) // 获取当前登录用户名
	if err != nil {
		Response(c)(err.Error(), CodeNeedLogin, nil)(Unauthorized)
		return
	}

	param := &struct {
		OutTradeNo string `gorm:"column:out_trade_no" json:"outTradeNo"` // 商户订单号
	}{}
	dingo.ErrorIf(c.ShouldBindJSON(param)).Unwrap()
	orderInfo := orders.New()
	global.Orm.Table("orders").
		Where("out_trade_no = ?", param.OutTradeNo).
		Find(&orderInfo)
	// 查询微信订单信息
	wc := logic.NewSettingLogic().GetPaySetting()
	resultData, err := wechatpay.ApiGetWeChatPayOrder(param.OutTradeNo, wc) // 查询微信订单
	if err != nil {
		//Response(c)("微信订单查询失败", CodeError, nil)(Error)
		return
	}

	// 添加订单操作日志
	orderLog := orderoperatelog.OrderOperateLog{}
	orderLog.TradeNo = resultData.Get("out_trade_no")
	orderLog.UserId = userId
	orderLog.UserName = userName
	orderLog.OperateType = 5
	orderLog.OperateIP = c.ClientIP()

	var b bool
	if orderInfo.Id > 0 {
		// 有订单更新
		// 更新微信订单状态
		// 1:等待下单 2:使用中 3:已撤销 4:交易失败 5:已完成 6:支付超时 7:待守约 10:已删除 11: 转入退款
		var status int8
		var stateDoning string
		switch resultData.Get("trade_state") {
		case "NOTPAY":
			status = 1 // CREATED 商户已创建服务订单

		case "SUCCESS":
			status = 5 // DONE 服务订单完成

		case "REVOKED":
			status = 3 // REVOKED 商户取消服务订单

		case "CLOSED":
			status = 4 // EXPIRED 服务订单已失效

		}
		if resultData.Get("trade_state") == "SUCCESS" {
			stateDoning = "COMPLETE"
		} else {
			stateDoning = resultData.Get("trade_state")
		}
		openId := wechatpay.NewPayData()
		_ = openId.FromJsonStr(resultData.Get("payer"))

		layout := "2006-01-02T15:04:05+08:00"
		str := resultData.Get("success_time")
		successTime, successTimeErr := time.Parse(layout, str)
		if successTimeErr != nil {
			log.Println("成功时间转化失败", successTimeErr, resultData.Get("success_time"))
		}

		// 订单金额信息，当支付成功时返回该字段。
		if resultData.Get("amount") != "" {
			apiData := wechatpay.NewPayData()
			_ = apiData.FromJsonStr(resultData.Get("amount"))
			state := apiData.Get("state")                                    // 状态 USER_PAYING：待支付 USER_PAID：已支付
			totalAmount, _ := strconv.ParseInt(apiData.Get("total"), 10, 64) // 总金额
			//paying_amount := apiData.Get("paying_amount") // 待支付金额
			paidAmount, _ := strconv.ParseInt(apiData.Get("payer_total"), 10, 64) // 已支付金额
			log.Println(state, totalAmount, paidAmount)                           // USER_PAID 100 0 100

			//log.Println(apiData.Get("details"))
			//var details []detailData
			//var details []map[string]interface{}
			//_ = json.Unmarshal([]byte(apiData.Get("details")), &details)
			//var transactionId string
			//if len(details) > 0 {
			//	transactionId = details[0]["transaction_id"].(string)
			//}
			//log.Println("打印测试订单详情", details)

			var s int8
			if state == "USER_PAYING" { // 待支付 --- 待守约
				s = 7
				m := orders.New()
				m.State = s
				m.Money = totalAmount
				m.MoneyStr = decimal.NewFromInt(totalAmount).Div(decimal.NewFromInt(100)).StringFixed(2)

				m.PayMoney = paidAmount
				m.PayMoneyStr = decimal.NewFromInt(paidAmount).Div(decimal.NewFromInt(100)).StringFixed(2)

				//m.PayAt = dingo.Time(wechatpay.ConvIntTime(fmt.Sprintf("%v", details[0]["paid_time"])))
				//m.SettlementState = 3
				//amount, _ := strconv.ParseInt(fmt.Sprintf("%v", details[0]["amount"]), 10, 64)
				//m.SettlementMoney = amount
				//m.SettlementMoneyStr = decimal.NewFromInt(amount).Div(decimal.NewFromInt(100)).StringFixed(2)
				m.TradeStateDesc = resultData.Get("trade_state_desc")
				m.TradeStateDoing = stateDoning
				m.TradeState = resultData.Get("state")
				m.TradeNo = resultData.Get("out_trade_no")
				m.Openid = openId.Get("openid")

				m.EndAt = dingo.Time(time.Now().Unix())
				m.OutTradeNo = resultData.Get("transaction_id")

				b = dao.NewOrderDao().UpdateOrderByTradeNo(m).Unwrap().(bool)
			} else {
				s = status
				m := orders.New()
				m.State = s
				m.Money = totalAmount
				m.MoneyStr = decimal.NewFromInt(totalAmount).Div(decimal.NewFromInt(100)).StringFixed(2)

				m.PayMoney = paidAmount
				m.PayMoneyStr = decimal.NewFromInt(paidAmount).Div(decimal.NewFromInt(100)).StringFixed(2)

				m.PayAt = dingo.Time(successTime.Unix())
				m.SettlementState = 3
				amount, _ := strconv.ParseInt(apiData.Get("total"), 10, 64)
				m.SettlementMoney = amount
				m.SettlementMoneyStr = decimal.NewFromInt(amount).Div(decimal.NewFromInt(100)).StringFixed(2)
				m.TradeStateDesc = resultData.Get("trade_state_desc")
				m.TradeStateDoing = stateDoning
				m.TradeState = resultData.Get("trade_state")
				m.TradeNo = resultData.Get("out_trade_no")
				m.Openid = resultData.Get("openid")

				m.EndAt = dingo.Time(time.Now().Unix())
				m.OutTradeNo = resultData.Get("transaction_id")

				b = dao.NewOrderDao().UpdateOrderByTradeNo(m).Unwrap().(bool)

				if !b {
					orderLog.ErrorType = int(CodeError)
					orderLog.ErrorMessage = "同步失败"
				}
				//重新分红订单
				logic.NewOrderLogic().HandleOrderDividendsByTradeNo(resultData.Get("out_trade_no"))
			}

		} else { // 订单金额为0时
			m := orders.New()
			m.State = status
			m.TradeStateDesc = resultData.Get("trade_state_desc")
			m.TradeStateDoing = stateDoning
			m.TradeState = resultData.Get("trade_state")
			m.TradeNo = resultData.Get("out_trade_no")
			m.Openid = openId.Get("openid")
			m.EndAt = dingo.Time(time.Now().Unix())
			b = dao.NewOrderDao().UpdateOrderByTradeNo(m).Unwrap().(bool)

			if !b {
				orderLog.ErrorType = int(CodeError)
				orderLog.ErrorMessage = "同步失败"
			}
			//重新分红订单
			logic.NewOrderLogic().HandleOrderDividendsByTradeNo(resultData.Get("out_trade_no"))
		}

	} else { // 新增
		deviceSn := wechatpay.NewPayData()
		openId := wechatpay.NewPayData()
		_ = deviceSn.FromJsonStr(resultData.Get("scene_info"))
		_ = openId.FromJsonStr(resultData.Get("payer"))
		memInfo := memberdao.NewMemberDao().GetMemberInfoByOpenid(openId.Get("openid")).Unwrap().(*membermodel.MembersModel)
		devInfo := dao.NewDeviceDao().FetchDeviceInfoWithType(deviceSn.Get("device_id")).Unwrap().(*devices.DeviceType)
		//ployInfo := dao.NewPloysDao().GetPlacePloyInfo(devInfo.PlaceId, devInfo.SharedMode).Unwrap().(*ploys.PloyModel) // 获取商户最新奖励规则配置

		var priceList []prices.PriceModel
		if devInfo.FeeMode == 1 { // 计时
			priceList = dao.NewPricesDao().GetPlacePriceByTypeId(devInfo.PlaceId, devInfo.DeviceTypeId, 1, 1, "create_at desc").Unwrap().([]prices.PriceModel)
		} else { // 套餐
			priceList = dao.NewPricesDao().GetPlacePriceByTypeId(devInfo.PlaceId, devInfo.DeviceTypeId, 1, 1, "pay_money asc").Unwrap().([]prices.PriceModel)
		}

		userInfo := dao.NewUserDao().GetUserInfoByPlaceId(devInfo.PlaceId).Unwrap().(*users.UserModel)
		uInfo := dao.GetParentUserInfoById(userInfo)

		isDraw := 0 // 不抽单
		layout := "2006-01-02T15:04:05+08:00"
		str := resultData.Get("success_time")
		successTime, successTimeErr := time.Parse(layout, str)
		if successTimeErr != nil {
			log.Println("成功时间转化失败", successTimeErr, resultData.Get("success_time"))
		}
		stamp := dingo.Time(successTime.Unix())
		amountInfo := wechatpay.NewPayData()
		_ = amountInfo.FromJsonStr(resultData.Get("amount"))

		//stamp, _ := time.ParseInLocation("20060102150405", timeRange.StartTime, time.Local)
		money, _ := strconv.ParseInt(amountInfo.Get("total"), 10, 64)
		//payMoney, _ := strconv.ParseInt(amountInfo.Get("payer_total"), 10, 64)

		// 更新微信订单状态
		// 1:等待下单 2:使用中 3:已撤销 4:交易失败 5:已完成 6:支付超时 7:待守约 10:已删除 11: 转入退款
		var status int8
		switch resultData.Get("trade_state") {
		case "NOTPAY":
			status = 1 // CREATED 商户已创建服务订单

		case "SUCCESS":
			status = 5 // DONE 服务订单完成

		case "REVOKED":
			status = 3 // REVOKED 商户取消服务订单

		case "CLOSED":
			status = 4 // EXPIRED 服务订单已失效

		}

		// 不存在  新增
		m := orders.New().Mutate(
			orders.WithAppid(resultData.Get("appid")),
			orders.WithDeviceSn(resultData.Get("attach")),
			orders.WithMchid(resultData.Get("mchid")),
			orders.WithOpenid(openId.Get("openid")),
			orders.WithOutTradeNo(resultData.Get("transaction_id")), // 微信订单号
			orders.WithTradeNo(resultData.Get("out_trade_no")),      // 商户订单号
			//orders.WithPayAt(dingo.Time(stamp.Unix())),                        // 支付时间
			orders.WithPayAt(dingo.Time(stamp)), // 支付时间
			//orders.WithTradeType(resultData.Get("trade_type")),                    // 订单支付类型 - 微信支付分支付
			orders.WithTradeType("PreAuthPay"), // 订单支付类型 - 微信支付分支付
			orders.WithMoney(money),
			orders.WithMoneyStr(decimal.NewFromInt(money).Div(decimal.NewFromInt(100)).StringFixed(2)),
			orders.WithSettlementMoney(money),
			orders.WithSettlementMoneyStr(decimal.NewFromInt(money).Div(decimal.NewFromInt(100)).StringFixed(2)),
			orders.WithTradeState(resultData.Get("trade_state")),          // 微信交易 状态
			orders.WithTradeStateDesc(resultData.Get("trade_state_desc")), // 微信交易状态描述
			orders.WithTradeStateDoing(resultData.Get("state_description")),
			orders.WithCreateAt(dingo.Time(time.Now().Unix())),
			orders.WithState(status),
			orders.WithOrderFrom("weixin"),
			orders.WithPayFrom(2), // 1免押 2押金
			orders.WithMemberId(memInfo.UUID),
			orders.WithMemberName(memInfo.NickName),
			orders.WithPlaceId(devInfo.PlaceId),
			orders.WithPlaceName(devInfo.PlaceName),
			orders.WithSharedMode(devInfo.SharedMode),
			orders.WithPayMoney(money),
			orders.WithPayMoneyStr(decimal.NewFromInt(money).Div(decimal.NewFromInt(100)).StringFixed(2)),
			orders.WithTitle(devInfo.DeviceName),
			orders.WithFeeMode(int8(devInfo.FeeMode)),
			orders.WithPayType(3),
			orders.WithProductId(priceList[0].ProductId),
			orders.WithIsDraw(int8(isDraw)), // 1抽单 0不抽单
			orders.WithIsTianHai(0),         // 0新系统  1天海
			orders.WithUserId(userInfo.ID),
			orders.WithUserName(userInfo.Name),
			orders.WithParentId(userInfo.ParentID),
			orders.WithAgentUserId(uInfo.ID),
			orders.WithSettlementWay(1),           // 未结算
			orders.WithProdType(devInfo.ProdType), // 设备类型  1  2  3
		)
		b = dao.NewOrderDao().InsertOrder(m).Unwrap().(bool)

		if !b {
			orderLog.ErrorType = int(CodeError)
			orderLog.ErrorMessage = "同步失败"
		}
		//重新分红订单
		logic.NewOrderLogic().HandleOrderDividendsByTradeNo(resultData.Get("out_trade_no"))
	}

	dingo.Task(logic.NewLogsLogic().InsertOrderLogLogic, func() {}, orderLog) // 添加订单操作日志
	Response(c)("", CodeSuccess, b)(OK)

}

// 催款
func HandelPromptOrder(ctx *gin.Context) {

}

// DrawOrder 抽单逻辑API
func DrawOrder(ctx *gin.Context) {
	//tradeNo := "a"
	// 订单详细
	//orderData := dao.NewOrderDao().GetOrderInfoByTradeNo(tradeNo).Unwrap().(*orders.OrderModel)
	// 获取网点抽单信息
	//placeDao := dao.NewPlaceDao().GetPlaceById(orderData.PlaceId).Unwrap().(*placemodel.PlaceModel)
	//抽单范围
	//drawScope := placeDao.DrawScope

	//var drawScopeArr []int
	//for i := 1; i < drawScope; i++ {
	//	drawScopeArr = append(drawScopeArr, i)
	//}
	//抽单的数量
	//drawNumber := placeDao.DrawNumber
	//currDrawNumber := drawNumber
	////当前抽单下标
	//drawIndex := placeDao.DrawIndex

	// 抽单结果
	//var drawArr []int
	//var otherDrawArr []int
	// 计算抽单
	//if placeDao.DrawType == 1 {
	//	// 抽单方式  1:固定位置抽取
	//	drawArr = regularDrawNumber(drawScopeArr, drawArr, otherDrawArr, drawNumber, currDrawNumber)
	//} else {
	//	// 抽单方式 2:轮次随机抽取
	//	drawArr = randomDrawNumber(drawScopeArr, drawArr, drawNumber)
	//}
	//
	//// 订单被抽中
	//if utils.ContainsInt(drawArr, drawIndex) {
	//	fmt.Println("haha，我中签了：", drawIndex)
	//	// 更新数据
	//	placeDao.IsDraw = 1
	//	// 如果 "当前抽单范围" 大于 "抽单范围" 那就重置
	//	if drawIndex >= drawScope {
	//		placeDao.DrawIndex = 1
	//	} else {
	//		placeDao.DrawIndex = placeDao.DrawIndex + 1
	//	}
	//	placeDao.DrawAt = dingo.Time(time.Now().Unix())
	//	dao.NewPlaceDao().UpdatePlaceById(placeDao)
	//
	//	// 订单表更新
	//	orderData.IsDraw = 1
	//	orderData.DrawAt = dingo.Time(time.Now().Unix())
	//	dao.NewOrderDao().UpdateOrder(orderData)
	//}

}

//var DrawScopeArr = []int{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20}
//var DrawScopeArr = []int{1,2,3,4,5,6,7,8,9,10}
//var DrawScopeArr = []int{2,4,6,8,10,12,14}
//var DrawNumber = 9
//var CurrDrawNumber = 9
//var DrawScopeArr []int
//var DrawNumber = 1
//var CurrDrawNumber = 1
//var DrawArr []int
//var OtherDrawArr []int

// 固定抽单法
func regularDrawNumber(drawScopeArr []int, drawArr []int, otherDrawArr []int, drawNumber int, currDrawNumber int) []int {
	var index = 1
	if len(drawArr) == currDrawNumber {
		println("退出递归：", len(drawArr))
		return drawArr
	}
	mod := len(drawScopeArr) / drawNumber
	for i := 0; i < len(drawScopeArr); i++ {
		// mod 等于1取值法
		if i == mod*index-1 {
			drawArr = append(drawArr, drawScopeArr[i])
			if mod == 1 {
				index = index + 2
			} else {
				index = index + 1
				if index > drawNumber {
					index = 1
				}
			}

		} else {
			otherDrawArr = append(otherDrawArr, drawScopeArr[i])
		}
	}
	drawScopeArr = otherDrawArr
	otherDrawArr = []int{}
	drawNumber = currDrawNumber - len(drawArr)

	return regularDrawNumber(drawScopeArr, drawArr, otherDrawArr, drawNumber, currDrawNumber)
}

// 随机抽单法
func randomDrawNumber(drawScopeArr []int, drawArr []int, drawNumber int) []int {

	if len(drawArr) == drawNumber {
		println("退出递归：", len(drawArr))
		return drawArr
	}
	// 随机数
	rand.Seed(time.Now().UnixNano())

	// 随机抽取一单
	drawNum := drawScopeArr[rand.Intn(len(drawScopeArr))]

	//查重
	exist := false
	for _, v := range drawArr {
		if v == drawNum {
			exist = true
			break
		}
	}

	if !exist {
		drawArr = append(drawArr, drawNum)
	}

	//递归
	return randomDrawNumber(drawScopeArr, drawArr, drawNumber)
}

//手动分红
func HandelHandmadeDividends(c *gin.Context) {
	userId, err := helper.GetUserIdFromCtx(c) // 获取当前登录用户ID
	if err != nil {
		Response(c)(err.Error(), CodeNeedLogin, nil)(Unauthorized)
		return
	}

	userName, err := helper.GetUserNameFromCtx(c) // 获取当前登录用户名
	if err != nil {
		Response(c)(err.Error(), CodeNeedLogin, nil)(Unauthorized)
		return
	}

	param := &struct {
		TradeNo string `json:"tradeNo"` // 商户订单号
	}{}
	dingo.ErrorIf(c.Bind(param)).Unwrap()
	orderInfo := dao.NewOrderDao().OrderInfoByTradeNo(param.TradeNo).Unwrap().(*orders.OrderModel)
	//查询订单对应的设备信息
	deviceInfo := dao.NewOrderDao().GetDeviceInfo(orderInfo.DeviceSn).Unwrap().(*devices.DeviceType)

	userInfo := dao.NewUserDao().GetUserInfoByPlaceId(orderInfo.PlaceId).Unwrap().(*users.UserModel)

	//查询订单是否分红
	count := dao.NewOrderDao().CountDividendsLogsByTradeNo(orderInfo.TradeNo, userInfo.ID).Unwrap().(int64)

	// 添加订单操作日志
	orderLog := orderoperatelog.OrderOperateLog{}
	orderLog.TradeNo = param.TradeNo
	orderLog.UserId = userId
	orderLog.UserName = userName
	orderLog.OperateType = 4
	orderLog.OperateIP = c.ClientIP()
	if count != 0 {
		orderLog.ErrorType = int(CodeError)
		orderLog.ErrorMessage = "此单已分红"
	}

	dingo.Task(logic.NewLogsLogic().InsertOrderLogLogic, func() {}, orderLog)

	if count != 0 {
		Response(c)("此单已分红", CodeError, param.TradeNo)(OK)
		return
	}

	dingo.Task(logic.NewOrderLogic().CalOrderDividends, func() {}, orderInfo, deviceInfo, orderInfo.SettlementMoney, int64(orderInfo.EndAt)) // 计算分红 - 异步任务

	Response(c)("", CodeSuccess, true)(OK)
}

//回滚分红
func HandelUndoDividends(c *gin.Context) {
	userId, err := helper.GetUserIdFromCtx(c) // 获取当前登录用户ID
	if err != nil {
		Response(c)(err.Error(), CodeNeedLogin, nil)(Unauthorized)
		return
	}

	userName, err := helper.GetUserNameFromCtx(c) // 获取当前登录用户名
	if err != nil {
		Response(c)(err.Error(), CodeNeedLogin, nil)(Unauthorized)
		return
	}

	param := &struct {
		TradeNo string `json:"tradeNo"` // 商户订单号
	}{}
	dingo.ErrorIf(c.Bind(param)).Unwrap()

	// 添加订单操作日志
	orderLog := orderoperatelog.OrderOperateLog{}
	orderLog.TradeNo = param.TradeNo
	orderLog.UserId = userId
	orderLog.UserName = userName
	orderLog.OperateType = 3
	orderLog.OperateIP = c.ClientIP()

	dingo.Task(logic.NewLogsLogic().InsertOrderLogLogic, func() {}, orderLog)

	//撤销分红操作
	Response(c)("", CodeSuccess, dao.NewOrderDao().DeleteDividendsLog(param.TradeNo).Unwrap())(OK)

}

//取消支付分订单
func HandleCancelEndOrder(c *gin.Context) {
	userId, err := helper.GetUserIdFromCtx(c) // 获取当前登录用户ID
	if err != nil {
		Response(c)(err.Error(), CodeNeedLogin, nil)(Unauthorized)
		return
	}

	userName, err := helper.GetUserNameFromCtx(c) // 获取当前登录用户名
	if err != nil {
		Response(c)(err.Error(), CodeNeedLogin, nil)(Unauthorized)
		return
	}

	param := request.CloseOrderReq{}
	dingo.ErrorIf(c.Bind(&param)).Unwrap()
	respData, err := logic.NewOrderLogic().HandleCancelEndOrder(&param)

	// 添加订单操作日志
	orderLog := orderoperatelog.OrderOperateLog{}
	orderLog.TradeNo = param.TradeNo
	orderLog.UserId = userId
	orderLog.UserName = userName
	orderLog.OperateType = 1
	orderLog.OperateIP = c.ClientIP()
	if err != nil {
		orderLog.ErrorType = int(CodeError)
		orderLog.ErrorMessage = err.Error()
	}

	dingo.Task(logic.NewLogsLogic().InsertOrderLogLogic, func() {}, orderLog)

	if err != nil {
		Response(c)(err.Error(), CodeError, false)(OK)
		return
	}

	log.Println("打印取消支付分订单返回结果 ------ ", respData)
	Response(c)("取消支付分订单成功", CodeSuccess, true)(OK)
}

//查询物流信息
func HandelGetCourier(c *gin.Context) {
	param := &struct {
		Com string `json:"com"` // 快递公司的代码
		Nu  string `json:"nu"`  //查询的快递单号
	}{}
	dingo.ErrorIf(c.Bind(&param)).Unwrap()

	url := fmt.Sprintf("https://www.kuaidi100.com/chaxun?com=%s&nu=%s", param.Com, param.Nu)
	resMap, err := authorized.GetRequest(url, nil)
	if err != nil {
		Response(c)("查询失败", CodeError, err.Error())(OK)
		return
	}

	Response(c)("查询成功", CodeSuccess, resMap)(OK)
}

func HandelSyncOrders(date string) (bool, error) {

	var tradeNo []string
	global.Orm.Table("orders").
		Select("trade_no").
		Where("state = 2 and DATE_FORMAT( FROM_UNIXTIME( create_at ), '%Y-%m-%d' ) <= ? and is_tianhai = 0", date).
		Find(&tradeNo)
	// 查询微信订单信息
	wc := logic.NewSettingLogic().GetPaySetting()
	var b bool
	for _, v := range tradeNo {
		resultData, err := wechatpay.ApiQueryPayScoreOrder(v, wc) // 查询微信订单
		if err != nil {
			log.Println(v)
			continue
		}

		if v != "" { // 有订单更新
			// 更新微信订单状态
			// 1:等待下单 2:使用中 3:已撤销 4:交易失败 5:已完成 6:支付超时 7:待守约 10:已删除 11: 转入退款
			var status int8
			var stateDesc, stateDoning string
			switch resultData.Get("state") {
			case "CREATED":
				status = 1 // CREATED 商户已创建服务订单
				stateDesc = "商户已创建服务订单"
			case "DOING":
				status = 2 // DOING 服务订单进行中
				stateDesc = "服务订单进行中"
			case "DONE":
				status = 5 // DONE 服务订单完成
				stateDesc = "服务订单完成"
			case "REVOKED":
				status = 3 // REVOKED 商户取消服务订单
				stateDesc = "商户取消服务订单"
			case "EXPIRED":
				status = 4 // EXPIRED 服务订单已失效
				stateDesc = "服务订单已失效"
			}
			if resultData.Get("state") == "DONE" {
				stateDoning = "COMPLETE"
			} else {
				stateDoning = resultData.Get("state_description")
			}

			// 结算金额大于0时才会返回 结算通知更新订单信息
			if resultData.Get("collection") != "" {
				apiData := wechatpay.NewPayData()
				_ = apiData.FromJsonStr(resultData.Get("collection"))
				state := apiData.Get("state")                                           // 状态 USER_PAYING：待支付 USER_PAID：已支付
				totalAmount, _ := strconv.ParseInt(apiData.Get("total_amount"), 10, 64) // 总金额
				//paying_amount := apiData.Get("paying_amount") // 待支付金额
				paidAmount, _ := strconv.ParseInt(apiData.Get("paid_amount"), 10, 64) // 已支付金额
				log.Println(state, totalAmount, paidAmount)                           // USER_PAID 100 0 100

				//log.Println(apiData.Get("details"))
				//var details []detailData
				var details []map[string]interface{}
				_ = json.Unmarshal([]byte(apiData.Get("details")), &details)
				var transactionId string
				if len(details) > 0 {
					transactionId = details[0]["transaction_id"].(string)
				}
				log.Println("打印测试订单详情", details)

				var s int8
				if state == "USER_PAYING" { // 待支付 --- 待守约
					s = 7
					m := orders.New()
					m.State = s
					m.Money = totalAmount
					m.MoneyStr = decimal.NewFromInt(totalAmount).Div(decimal.NewFromInt(100)).StringFixed(2)

					m.PayMoney = paidAmount
					m.PayMoneyStr = decimal.NewFromInt(paidAmount).Div(decimal.NewFromInt(100)).StringFixed(2)

					//m.PayAt = dingo.Time(wechatpay.ConvIntTime(fmt.Sprintf("%v", details[0]["paid_time"])))
					//m.SettlementState = 3
					//amount, _ := strconv.ParseInt(fmt.Sprintf("%v", details[0]["amount"]), 10, 64)
					//m.SettlementMoney = amount
					//m.SettlementMoneyStr = decimal.NewFromInt(amount).Div(decimal.NewFromInt(100)).StringFixed(2)
					m.TradeStateDesc = stateDesc
					m.TradeStateDoing = stateDoning
					m.TradeState = resultData.Get("state")
					m.TradeNo = resultData.Get("out_order_no")
					m.Openid = resultData.Get("openid")

					m.EndAt = dingo.Time(time.Now().Unix())
					m.OutTradeNo = transactionId

					b = dao.NewOrderDao().UpdateOrderByTradeNo(m).Unwrap().(bool)
				} else {
					s = status
					m := orders.New()
					m.State = s
					m.Money = totalAmount
					m.MoneyStr = decimal.NewFromInt(totalAmount).Div(decimal.NewFromInt(100)).StringFixed(2)

					m.PayMoney = paidAmount
					m.PayMoneyStr = decimal.NewFromInt(paidAmount).Div(decimal.NewFromInt(100)).StringFixed(2)

					m.PayAt = dingo.Time(wechatpay.ConvIntTime(fmt.Sprintf("%v", details[0]["paid_time"])))
					m.SettlementState = 3
					amount, _ := strconv.ParseInt(fmt.Sprintf("%v", details[0]["amount"]), 10, 64)
					m.SettlementMoney = amount
					m.SettlementMoneyStr = decimal.NewFromInt(amount).Div(decimal.NewFromInt(100)).StringFixed(2)
					m.TradeStateDesc = stateDesc
					m.TradeStateDoing = stateDoning
					m.TradeState = resultData.Get("state")
					m.TradeNo = resultData.Get("out_order_no")
					m.Openid = resultData.Get("openid")

					m.EndAt = dingo.Time(time.Now().Unix())
					m.OutTradeNo = transactionId

					b = dao.NewOrderDao().UpdateOrderByTradeNo(m).Unwrap().(bool)
				}

			} else { // 订单金额为0时
				m := orders.New()
				m.State = status
				m.TradeStateDesc = stateDesc
				m.TradeStateDoing = stateDoning
				m.TradeState = resultData.Get("state")
				m.TradeNo = resultData.Get("out_order_no")
				m.Openid = resultData.Get("openid")
				m.EndAt = dingo.Time(time.Now().Unix())
				b = dao.NewOrderDao().UpdateOrderByTradeNo(m).Unwrap().(bool)
			}
		} else { // 新增
			memInfo := memberdao.NewMemberDao().GetMemberInfoByOpenid(resultData.Get("openid")).Unwrap().(*membermodel.MembersModel)
			devInfo := dao.NewDeviceDao().FetchDeviceInfoWithType(resultData.Get("attach")).Unwrap().(*devices.DeviceType)
			//ployInfo := dao.NewPloysDao().GetPlacePloyInfo(devInfo.PlaceId, devInfo.SharedMode).Unwrap().(*ploys.PloyModel) // 获取商户最新奖励规则配置

			var priceList []prices.PriceModel
			if devInfo.FeeMode == 1 { // 计时
				priceList = dao.NewPricesDao().GetPlacePriceByTypeId(devInfo.PlaceId, devInfo.DeviceTypeId, 1, 1, "create_at desc").Unwrap().([]prices.PriceModel)
			} else { // 套餐
				priceList = dao.NewPricesDao().GetPlacePriceByTypeId(devInfo.PlaceId, devInfo.DeviceTypeId, 1, 1, "pay_money asc").Unwrap().([]prices.PriceModel)
			}

			userInfo := dao.NewUserDao().GetUserInfoByPlaceId(devInfo.PlaceId).Unwrap().(*users.UserModel)
			uInfo := dao.GetParentUserInfoById(userInfo)

			isDraw := 0 // 不抽单

			timeRange := &struct {
				StartTime string `json:"start_time"`
				EndTime   string `json:"end_time"`
			}{}
			_ = json.Unmarshal([]byte(resultData.Get("time_range")), timeRange)
			stamp := wechatpay.ConvIntTime(timeRange.StartTime)
			//stamp, _ := time.ParseInLocation("20060102150405", timeRange.StartTime, time.Local)
			money, _ := strconv.ParseInt(resultData.Get("total_amount"), 10, 64)

			// 1:等待下单 2:使用中 3:已撤销 4:交易失败 5:已完成 6:支付超时 7:待守约 10:已删除 11: 转入退款
			var status int8
			var stateDesc string
			switch resultData.Get("state") {
			case "CREATED":
				status = 1 // CREATED 商户已创建服务订单
				stateDesc = "商户已创建服务订单"
			case "DOING":
				status = 2 // DOING 服务订单进行中
				stateDesc = "服务订单进行中"
			case "DONE":
				status = 5 // DONE 服务订单完成
				stateDesc = "服务订单完成"
			case "REVOKED":
				status = 3 // REVOKED 商户取消服务订单
				stateDesc = "商户取消服务订单"
			case "EXPIRED":
				status = 4 // EXPIRED 服务订单已失效
				stateDesc = "服务订单已失效"
			}

			// 不存在  新增
			m := orders.New().Mutate(
				orders.WithAppid(resultData.Get("appid")),
				orders.WithDeviceSn(resultData.Get("attach")),
				orders.WithMchid(resultData.Get("mchid")),
				orders.WithOpenid(resultData.Get("openid")),
				orders.WithOutTradeNo(resultData.Get("order_id")),  // 微信订单号
				orders.WithTradeNo(resultData.Get("out_order_no")), // 商户订单号
				//orders.WithPayAt(dingo.Time(stamp.Unix())),                        // 支付时间
				orders.WithPayAt(dingo.Time(stamp)), // 支付时间
				//orders.WithTradeType(resultData.Get("trade_type")),                    // 订单支付类型 - 微信支付分支付
				orders.WithTradeType("PreAuthPay"), // 订单支付类型 - 微信支付分支付
				orders.WithMoney(money),
				orders.WithMoneyStr(decimal.NewFromInt(money).Div(decimal.NewFromInt(100)).StringFixed(2)),
				orders.WithTradeState(resultData.Get("state")), // 微信交易 状态
				orders.WithTradeStateDesc(stateDesc),           // 微信交易状态描述
				orders.WithTradeStateDoing(resultData.Get("state_description")),
				orders.WithCreateAt(dingo.Time(time.Now().Unix())),
				orders.WithState(status),
				orders.WithOrderFrom("weixin"),
				orders.WithPayFrom(1), // 1免押 2押金
				orders.WithMemberId(memInfo.UUID),
				orders.WithMemberName(memInfo.NickName),
				orders.WithPlaceId(devInfo.PlaceId),
				orders.WithPlaceName(devInfo.PlaceName),
				orders.WithSharedMode(devInfo.SharedMode),
				orders.WithPayMoney(money),
				orders.WithPayMoneyStr(decimal.NewFromInt(money).Div(decimal.NewFromInt(100)).StringFixed(2)),
				orders.WithTitle(devInfo.DeviceName),
				orders.WithFeeMode(int8(devInfo.FeeMode)),
				orders.WithPayType(3),
				orders.WithProductId(priceList[0].ProductId),
				orders.WithIsDraw(int8(isDraw)), // 1抽单 0不抽单
				orders.WithIsTianHai(0),         // 0新系统  1天海
				orders.WithUserId(userInfo.ID),
				orders.WithUserName(userInfo.Name),
				orders.WithParentId(userInfo.ParentID),
				orders.WithAgentUserId(uInfo.ID),
				orders.WithSettlementWay(1),           // 未结算
				orders.WithProdType(devInfo.ProdType), // 设备类型  1  2  3
			)
			b = dao.NewOrderDao().InsertOrder(m).Unwrap().(bool)
		}

	}

	return b, nil
}

//查询客诉列表
func HandelComplaintsList(c *gin.Context) {
	param := &request.ComplaintsReq{}
	dingo.ErrorIf(c.ShouldBind(param)).Unwrap()
	urlStr := ""
	//complaintsModel := &complaints.WeChatComplaints{}
	if param.PageNo > 0 {
		urlStr += "limit=" + strconv.Itoa(param.PageSize) + "&"
	}
	if param.PageSize > 0 {
		urlStr += "offset=" + strconv.Itoa(param.PageSize*(param.PageNo-1)) + "&"
	}
	//开始时间当前默认时间
	if param.BeginDate == "" {
		urlStr += "begin_date=" + time.Now().Format("2006-01-02") + "&"
	} else {
		urlStr += "begin_date=" + param.BeginDate + "&"
	}
	//结束时间，默认三十天
	if param.EndDate == "" {
		urlStr += "end_date=" + time.Now().AddDate(0, 0, 29).Format("2006-01-02") + "&"

	} else {
		urlStr += "end_date=" + param.BeginDate + "&"
	}
	wc := logic.NewSettingLogic().GetPaySetting()

	urlStr += "complainted_mchid=" + wc.MchId

	resMap, err := wechatpay.ApiGetComplaintsList(urlStr, wc)
	if err != nil {
		Response(c)("查询失败", CodeInternalServerError, resMap)(OK)
		return
	}

	data := resMap["data"].([]interface{})
	var BeijingLocation = time.FixedZone("Asia/Shanghai", 8*60*60)
	for _, v := range data {
		mapData := v.(map[string]interface{})
		if mapData["payer_phone"] != nil {
			cipherText := mapData["payer_phone"].(string)
			mapData["payer_phone"] = wechatpay.DecryptOAEP(cipherText, wc.ApiclientKeyPath)
		}

		layout := "2006-01-02T15:04:05+08:00"
		successTime, _ := time.ParseInLocation(layout, mapData["complaint_time"].(string), BeijingLocation)
		//successTime.AddDate(0, 0, -1)
		mapData["complaint_time"] = successTime.Format("2006-01-02 15:04:05")

		var stateStr string
		state := mapData["complaint_state"].(string)

		switch state {
		case "PENDING":
			stateStr = "待处理"
		case "PROCESSING":
			stateStr = "处理中"
		case "PROCESSED":
			stateStr = "已处理完成"
		}

		mapData["complaint_state"] = stateStr

	}

	Response(c)("查询成功", CodeSuccess, resMap)(OK)
	return
}

//查询客诉详情 200202520211112120292883702
func HandelComplaintsDetail(c *gin.Context) {
	param := &request.ComplaintsReq{}
	dingo.ErrorIf(c.ShouldBind(param)).Unwrap()

	if param.ComplaintId == "" {
		Response(c)("查询失败，请给出正确的投诉单号", CodeInvalidParam, nil)(OK)
		return
	}

	wc := logic.NewSettingLogic().GetPaySetting()
	resMap, err := wechatpay.ApiGetComplaintsDetails(param.ComplaintId, wc)
	if err != nil {
		Response(c)("查询失败", CodeInternalServerError, resMap)(OK)
		return
	}

	cipherText := resMap["payer_phone"].(string)

	resMap["payer_phone"] = wechatpay.DecryptOAEP(cipherText, wc.ApiclientKeyPath)
	fmt.Println(cipherText, resMap["payer_phone"])

	var BeijingLocation = time.FixedZone("Asia/Shanghai", 8*60*60)
	layout := "2006-01-02T15:04:05+08:00"
	successTime, _ := time.ParseInLocation(layout, resMap["complaint_time"].(string), BeijingLocation)
	//successTime.AddDate(0, 0, -1)
	resMap["complaint_time"] = successTime.Format("2006-01-02 15:04:05")

	Response(c)("查询成功", CodeSuccess, resMap)(OK)
	return
}

//查询协商历史
func HandelComplaintsHistory(c *gin.Context) {
	param := &request.ComplaintsReq{}
	dingo.ErrorIf(c.ShouldBind(param)).Unwrap()
	urlStr := "/" + param.ComplaintId + "/negotiation-historys"
	//complaintsModel := &complaints.WeChatComplaints{}
	if param.PageNo > 0 {
		urlStr += "?limit=" + strconv.Itoa(param.PageNo) + "&"
	}
	if param.PageSize > 0 {
		urlStr += "offset=" + strconv.Itoa(param.PageSize) + "&"
	}

	wc := logic.NewSettingLogic().GetPaySetting()
	resMap, err := wechatpay.ApiGetComplaintsNegotiationHistory(urlStr, wc)
	if err != nil {
		Response(c)("查询失败", CodeInternalServerError, resMap)(OK)
		return
	}
	data := resMap["data"].([]interface{})
	var BeijingLocation = time.FixedZone("Asia/Shanghai", 8*60*60)
	for _, v := range data {
		mapData := v.(map[string]interface{})
		//cipherText := mapData["payer_phone"].(string)
		//mapData["payer_phone"] = wechatpay.DecryptOAEP(cipherText, wc.ApiclientKeyPath)

		layout := "2006-01-02T15:04:05+08:00"
		successTime, _ := time.ParseInLocation(layout, mapData["operate_time"].(string), BeijingLocation)
		mapData["operate_time"] = successTime.Format("2006-01-02 15:04:05")

	}

	Response(c)("查询成功", CodeSuccess, resMap)(OK)
	return
}

//提交回复
func HandelComplaintsSubmit(c *gin.Context) {
	param := &request.ComplaintsSubmitReq{}
	dingo.ErrorIf(c.Bind(param)).Unwrap()
	wc := logic.NewSettingLogic().GetPaySetting()
	err := wechatpay.ApiSubmitReplyComplaints(param, wc)
	if err != nil {
		Response(c)("提交失败", CodeInternalServerError, "")(OK)
		return
	}
	Response(c)("查询成功", CodeSuccess, "")(OK)
}

//反馈完成
func HandelComplaintsComplete(c *gin.Context) {
	param := &request.ComplaintsSubmitReq{}
	dingo.ErrorIf(c.Bind(param)).Unwrap()
	wc := logic.NewSettingLogic().GetPaySetting()
	err := wechatpay.ApiFeedbackSolveComplaints(param.ComplaintId, wc)
	if err != nil {
		Response(c)("提交失败", CodeInternalServerError, "")(OK)
		return
	}
	Response(c)("查询成功", CodeSuccess, "")(OK)
}

//商户上传图片
func HandelComplaintsUploadImg(c *gin.Context) {
	file, err := c.FormFile("file")
	if err != nil {
		Response(c)("图片上传失败", CodeInvalidParam, err)(OK)
		return
	}
	wc := logic.NewSettingLogic().GetPaySetting()
	ctx := context.Background()
	fileIO, err := file.Open()

	res, err := wechatpay.ApiMediaUpload(ctx, fileIO, wc)
	if err != nil {
		Response(c)("图片上传失败", CodeInternalServerError, "")(OK)
	}
	Response(c)("上传成功", CodeSuccess, res)(OK)
}

//查询投诉列表保存入库
func HandlerRefreshComplaintsLog(c *gin.Context) {
	param := &request.ComplaintsReq{}
	dingo.ErrorIf(c.ShouldBind(param)).Unwrap()
	urlStr := ""
	//开始时间当前默认时间
	if param.BeginDate == "" {
		urlStr += "begin_date=" + time.Now().Format("2006-01-02") + "&"
	} else {
		urlStr += "begin_date=" + param.BeginDate + "&"
	}
	//结束时间，默认三十天
	if param.EndDate == "" {
		urlStr += "end_date=" + time.Now().AddDate(0, 0, 29).Format("2006-01-02") + "&"

	} else {
		urlStr += "end_date=" + param.BeginDate + "&"
	}
	wc := logic.NewSettingLogic().GetPaySetting()
	urlStr += "complainted_mchid=" + wc.MchId

	resMap, err := wechatpay.ApiGetComplaintsList(urlStr, wc)
	if err != nil {
		Response(c)("查询失败", CodeInternalServerError, resMap)(OK)
		return
	}
	var totalCount float64
	if resMap["total_count"] != nil {
		totalCount = resMap["total_count"].(float64)
	}
	err = logic.NewOrderLogic().RefreshComplaintsLog(int(totalCount), urlStr)
	if err != nil {
		Response(c)("入库失败", CodeInvalidParam, "")(OK)
	}
	Response(c)("入库成功", CodeSuccess, "")(OK)
	return
}
